From 2c28fb640747244df7009a86df557d22a07ad5b1 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Sat, 15 Oct 2022 21:52:10 +0300 Subject: [PATCH] it works --- src/glfb.c | 10 ++++---- src/main.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/voxscape.c | 56 ++++++++++++++++++++++++++++++++++++++++----- src/voxscape.h | 2 ++ 4 files changed, 124 insertions(+), 13 deletions(-) diff --git a/src/glfb.c b/src/glfb.c index a939ba6..1a39686 100644 --- a/src/glfb.c +++ b/src/glfb.c @@ -102,12 +102,12 @@ void glfb_display(void) glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_TRIANGLES); - glTexCoord2f(0, 0); - glVertex2f(-1, -1); - glTexCoord2f(tex_sx * 2.0f, 0); - glVertex2f(3, -1); glTexCoord2f(0, tex_sy * 2.0f); - glVertex2f(-1, 3); + glVertex2f(-1, -3); + glTexCoord2f(tex_sx * 2.0f, 0); + glVertex2f(3, 1); + glTexCoord2f(0, 0); + glVertex2f(-1, 1); glEnd(); } diff --git a/src/main.c b/src/main.c index 0201cbc..c2192ee 100644 --- a/src/main.c +++ b/src/main.c @@ -7,12 +7,20 @@ #include "glfb.h" #include "voxscape.h" +enum { + INP_FWD = 1, + INP_BACK = 2, + INP_LEFT = 4, + INP_RIGHT = 8 +}; + int init(void); void cleanup(void); void display(void); void idle(void); void reshape(int x, int y); void keyb(unsigned char key, int x, int y); +void keyb_up(unsigned char key, int x, int y); int win_width, win_height; @@ -20,6 +28,9 @@ int win_width, win_height; #define FB_H 480 unsigned int fb[FB_W * FB_H]; +unsigned int input; +int32_t pos[2]; + struct voxscape *vox; @@ -33,6 +44,7 @@ int main(int argc, char **argv) glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyb); + glutKeyboardUpFunc(keyb_up); glutIdleFunc(idle); if(init() == -1) { @@ -47,12 +59,15 @@ int main(int argc, char **argv) int init(void) { + pos[0] = 512 << 16; + pos[1] = 512 << 16; + if(!(vox = vox_open("data/height.png", "data/color.png"))) { return -1; } vox_framebuf(vox, FB_W, FB_H, fb); - vox_proj(vox, 45, 5, 100); - vox_view(vox, 512 << 16, 512 << 16, 0); + vox_proj(vox, 45, 1, 200); + vox_view(vox, pos[0], pos[1], 0); glfb_setup(FB_W, FB_H, GLFB_RGBA32, FB_W * 4); return 0; @@ -63,9 +78,25 @@ void cleanup(void) vox_free(vox); } +#define WALK_SPEED 0x40000 +void update(void) +{ + if(input & INP_FWD) pos[1] += WALK_SPEED; + if(input & INP_BACK) pos[1] -= WALK_SPEED; + if(input & INP_LEFT) pos[0] -= WALK_SPEED; + if(input & INP_RIGHT) pos[0] += WALK_SPEED; + + vox_view(vox, pos[0], pos[1], 0); +} + void display(void) { + update(); + + memset(fb, 0, sizeof fb); + vox_render(vox); + vox_sky_grad(vox, 0xcc77ff, 0x5588cc); glfb_update(fb); glfb_display(); @@ -93,6 +124,40 @@ void keyb(unsigned char key, int x, int y) case 27: exit(0); + case 'w': + input |= INP_FWD; + break; + case 's': + input |= INP_BACK; + break; + case 'a': + input |= INP_LEFT; + break; + case 'd': + input |= INP_RIGHT; + break; + + default: + break; + } +} + +void keyb_up(unsigned char key, int x, int y) +{ + switch(key) { + case 'w': + input &= ~INP_FWD; + break; + case 's': + input &= ~INP_BACK; + break; + case 'a': + input &= ~INP_LEFT; + break; + case 'd': + input &= ~INP_RIGHT; + break; + default: break; } diff --git a/src/voxscape.c b/src/voxscape.c index 2ccb5f9..28a02bf 100644 --- a/src/voxscape.c +++ b/src/voxscape.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include "voxscape.h" @@ -64,7 +65,8 @@ struct voxscape *vox_create(int xsz, int ysz) vox->xshift++; } - vox->proj_dist = 2; /* TODO */ + vox->vheight = 50; + vox->proj_dist = 4; /* TODO */ return vox; } @@ -187,7 +189,7 @@ void vox_begin(struct voxscape *vox) if(!(vox->valid & SLICELEN)) { float theta = (float)vox->fov * M_PI / 360.0f; /* half angle */ for(i=0; inslices; i++) { - vox->slicelen[i] = (int32_t)((vox->znear + i) * tan(theta) * 2.0f * 65536.0f); + vox->slicelen[i] = (int32_t)((vox->znear + i) * tan(theta) * 10.0f * 65536.0f); } vox->valid |= SLICELEN; } @@ -204,16 +206,17 @@ void vox_render_slice(struct voxscape *vox, int n) xstep = len / vox->fbwidth; x = vox->x - xstep * (vox->fbwidth >> 1); - y = vox->y + (vox->znear << 16); + y = vox->y + ((vox->znear + n) << 16); for(i=0; ifbwidth; i++) { tx = (x >> 16) & vox->xmask; ty = (y >> 16) & vox->ymask; - hval = vox->height[(ty << vox->xshift) + tx]; - hval = (hval - vox->vheight) * vox->proj_dist / (vox->znear + i); + hval = vox->height[(ty << vox->xshift) + tx] - 80; + hval = hval * 80 / (vox->znear + n) + 250; + if(hval > vox->fbheight) hval = vox->fbheight; if(hval > vox->coltop[i]) { color = vox->color[(ty << vox->xshift) + tx]; - colstart = vox->fbheight - 1 - hval; + colstart = vox->fbheight - hval; colheight = hval - vox->coltop[i]; fbptr = vox->fb + colstart * vox->fbwidth + i; @@ -221,8 +224,49 @@ void vox_render_slice(struct voxscape *vox, int n) *fbptr = color; fbptr += vox->fbwidth; } + vox->coltop[i] = hval; } x += xstep; } } + +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; + uint32_t *grad, *fbptr; + + grad = alloca(vox->fbheight * sizeof *grad); + + r0 = ctop >> 16; + g0 = (ctop >> 8) & 0xff; + b0 = ctop & 0xff; + r1 = chor >> 16; + g1 = (chor >> 8) & 0xff; + b1 = chor & 0xff; + + for(i=0; i> 8; + g = ((g0 << 8) + (g1 - g0) * t) >> 8; + b = ((b0 << 8) + (b1 - b0) * t) >> 8; + assert(r >= 0 && r < 256); + assert(g >= 0 && g < 256); + assert(b >= 0 && b < 256); + grad[i] = (r << 16) | (g << 8) | b; + } + for(i=d; ifbheight; i++) { + grad[i] = chor; + } + + for(i=0; ifbwidth; i++) { + fbptr = vox->fb + i; + colheight = vox->fbheight - vox->coltop[i]; + for(j=0; jfbwidth; + } + } +} diff --git a/src/voxscape.h b/src/voxscape.h index bd7d3a1..c0e386f 100644 --- a/src/voxscape.h +++ b/src/voxscape.h @@ -18,4 +18,6 @@ void vox_render(struct voxscape *vox); void vox_begin(struct voxscape *vox); void vox_render_slice(struct voxscape *vox, int n); +void vox_sky_grad(struct voxscape *vox, uint32_t chor, uint32_t ctop); + #endif /* VOXSCAPE_H_ */ -- 1.7.10.4