interpolation
[voxscape] / src / main.c
index 0201cbc..bcf2250 100644 (file)
@@ -6,6 +6,16 @@
 #include <GL/glut.h>
 #include "glfb.h"
 #include "voxscape.h"
+#include "lut.h"
+
+enum {
+       INP_FWD         = 0x01,
+       INP_BACK        = 0x02,
+       INP_LEFT        = 0x04,
+       INP_RIGHT       = 0x08,
+       INP_LTURN       = 0x10,
+       INP_RTURN       = 0x20
+};
 
 int init(void);
 void cleanup(void);
@@ -13,6 +23,9 @@ 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);
+void mouse(int bn, int st, int x, int y);
+void motion(int x, int y);
 
 int win_width, win_height;
 
@@ -20,8 +33,17 @@ int win_width, win_height;
 #define FB_H   480
 unsigned int fb[FB_W * FB_H];
 
+int mouse_x, mouse_y, mwarp, mbstate[3];
+int hfilt = VOX_LINEAR, cfilt = VOX_LINEAR;
+
+unsigned int input;
+int32_t pos[2], angle;
+
 struct voxscape *vox;
 
+#define COLOR_HORIZON  0xcc77ff
+#define COLOR_ZENITH   0x5588cc
+
 
 int main(int argc, char **argv)
 {
@@ -31,9 +53,12 @@ int main(int argc, char **argv)
        glutCreateWindow("voxel landscape test");
 
        glutDisplayFunc(display);
+       glutIdleFunc(idle);
        glutReshapeFunc(reshape);
        glutKeyboardFunc(keyb);
-       glutIdleFunc(idle);
+       glutKeyboardUpFunc(keyb_up);
+       glutMouseFunc(mouse);
+       glutMotionFunc(motion);
 
        if(init() == -1) {
                return 1;
@@ -47,12 +72,18 @@ int main(int argc, char **argv)
 
 int init(void)
 {
+       init_lut();
+
+       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_framebuf(vox, FB_W, FB_H, fb, -1);
+       vox_proj(vox, 45, 1, 300);
+       vox_fog(vox, 260, COLOR_HORIZON);
+       vox_filter(vox, hfilt, cfilt);
 
        glfb_setup(FB_W, FB_H, GLFB_RGBA32, FB_W * 4);
        return 0;
@@ -63,15 +94,60 @@ void cleanup(void)
        vox_free(vox);
 }
 
+#define WALK_SPEED     0x40000
+#define TURN_SPEED     0x100
+
+void update(void)
+{
+       int32_t fwd[2], right[2];
+
+       if(input & INP_LTURN) angle += TURN_SPEED;
+       if(input & INP_RTURN) angle -= TURN_SPEED;
+
+       fwd[0] = -SIN(angle);
+       fwd[1] = COS(angle);
+       right[0] = fwd[1];
+       right[1] = -fwd[0];
+
+       if(input & INP_FWD) {
+               pos[0] += fwd[0];
+               pos[1] += fwd[1];
+       }
+       if(input & INP_BACK) {
+               pos[0] -= fwd[0];
+               pos[1] -= fwd[1];
+       }
+       if(input & INP_RIGHT) {
+               pos[0] += right[0];
+               pos[1] += right[1];
+       }
+       if(input & INP_LEFT) {
+               pos[0] -= right[0];
+               pos[1] -= right[1];
+       }
+
+       vox_view(vox, pos[0], pos[1], -30, angle);
+}
+
 void display(void)
 {
+       update();
+
+       memset(fb, 0, sizeof fb);
+
        vox_render(vox);
+       vox_sky_grad(vox, COLOR_HORIZON, COLOR_ZENITH);
 
        glfb_update(fb);
        glfb_display();
 
        glutSwapBuffers();
        assert(glGetError() == GL_NO_ERROR);
+
+       if(mbstate[0]) {
+               mwarp = 1;
+               glutWarpPointer(win_width / 2, win_height / 2);
+       }
 }
 
 void idle(void)
@@ -93,7 +169,102 @@ 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;
+       case 'q':
+               input |= INP_LTURN;
+               break;
+       case 'e':
+               input |= INP_RTURN;
+               break;
+
+       case 'h':
+               hfilt ^= 1;
+               printf("filtering: height(%s) color(%s)\n", hfilt ? "linear" : "nearest",
+                               cfilt ? "linear" : "nearest");
+               vox_filter(vox, hfilt, cfilt);
+               break;
+
+       case 'c':
+               cfilt ^= 1;
+               vox_filter(vox, hfilt, cfilt);
+               printf("filtering: height(%s) color(%s)\n", hfilt ? "linear" : "nearest",
+                               cfilt ? "linear" : "nearest");
+               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;
+       case 'q':
+               input &= ~INP_LTURN;
+               break;
+       case 'e':
+               input &= ~INP_RTURN;
+               break;
+
+       default:
+               break;
+       }
+}
+
+void mouse(int bn, int st, int x, int y)
+{
+       int bidx = bn - GLUT_LEFT_BUTTON;
+
+       if(bidx < 3) {
+               mbstate[bidx] = st == GLUT_DOWN;
+       }
+       mouse_x = x;
+       mouse_y = y;
+
+       if(st == GLUT_DOWN) {
+               glutSetCursor(GLUT_CURSOR_NONE);
+       } else {
+               glutSetCursor(GLUT_CURSOR_LEFT_ARROW);
+       }
+}
+
+void motion(int x, int y)
+{
+       int dx = x - mouse_x;
+       int dy = y - mouse_y;
+       mouse_x = x;
+       mouse_y = y;
+
+       if(mwarp) {
+               mwarp = 0;
+               return;
+       }
+       if(!(dx | dy)) return;
+
+       if(mbstate[0]) {
+               angle -= dx << 6;
+       }
+}