fixed fog regression
[voxscape] / src / main.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <math.h>
5 #include <assert.h>
6 #include <GL/glut.h>
7 #include "glfb.h"
8 #include "voxscape.h"
9 #include "lut.h"
10
11 enum {
12         INP_FWD         = 0x01,
13         INP_BACK        = 0x02,
14         INP_LEFT        = 0x04,
15         INP_RIGHT       = 0x08,
16         INP_LTURN       = 0x10,
17         INP_RTURN       = 0x20
18 };
19
20 int init(void);
21 void cleanup(void);
22 void display(void);
23 void idle(void);
24 void reshape(int x, int y);
25 void keyb(unsigned char key, int x, int y);
26 void keyb_up(unsigned char key, int x, int y);
27 void mouse(int bn, int st, int x, int y);
28 void motion(int x, int y);
29
30 int win_width, win_height;
31
32 #define FB_W    640
33 #define FB_H    480
34 unsigned int fb[FB_W * FB_H];
35
36 int mouse_x, mouse_y, mwarp, mbstate[3];
37 int hfilt = VOX_LINEAR, cfilt = VOX_LINEAR;
38
39 unsigned int input;
40 int32_t pos[2], angle;
41
42 struct voxscape *vox;
43
44 #define COLOR_HORIZON   0xcc77ff
45 #define COLOR_ZENITH    0x5588cc
46
47
48 int main(int argc, char **argv)
49 {
50         glutInit(&argc, argv);
51         glutInitWindowSize(1280, 960);
52         glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
53         glutCreateWindow("voxel landscape test");
54
55         glutDisplayFunc(display);
56         glutIdleFunc(idle);
57         glutReshapeFunc(reshape);
58         glutKeyboardFunc(keyb);
59         glutKeyboardUpFunc(keyb_up);
60         glutMouseFunc(mouse);
61         glutMotionFunc(motion);
62
63         if(init() == -1) {
64                 return 1;
65         }
66         atexit(cleanup);
67
68         glutMainLoop();
69         return 0;
70 }
71
72
73 int init(void)
74 {
75         init_lut();
76
77         pos[0] = 512 << 16;
78         pos[1] = 512 << 16;
79
80         if(!(vox = vox_open("data/height.png", "data/color.png"))) {
81                 return -1;
82         }
83         vox_framebuf(vox, FB_W, FB_H, fb, -1);
84         vox_proj(vox, 45, 1, 300);
85         vox_fog(vox, 260, COLOR_HORIZON);
86         vox_filter(vox, hfilt, cfilt);
87
88         glfb_setup(FB_W, FB_H, GLFB_RGBA32, FB_W * 4);
89         return 0;
90 }
91
92 void cleanup(void)
93 {
94         vox_free(vox);
95 }
96
97 #define WALK_SPEED      0x40000
98 #define TURN_SPEED      0x100
99
100 void update(void)
101 {
102         int32_t fwd[2], right[2];
103
104         if(input & INP_LTURN) angle += TURN_SPEED;
105         if(input & INP_RTURN) angle -= TURN_SPEED;
106
107         fwd[0] = -SIN(angle);
108         fwd[1] = COS(angle);
109         right[0] = fwd[1];
110         right[1] = -fwd[0];
111
112         if(input & INP_FWD) {
113                 pos[0] += fwd[0];
114                 pos[1] += fwd[1];
115         }
116         if(input & INP_BACK) {
117                 pos[0] -= fwd[0];
118                 pos[1] -= fwd[1];
119         }
120         if(input & INP_RIGHT) {
121                 pos[0] += right[0];
122                 pos[1] += right[1];
123         }
124         if(input & INP_LEFT) {
125                 pos[0] -= right[0];
126                 pos[1] -= right[1];
127         }
128
129         vox_view(vox, pos[0], pos[1], -30, angle);
130 }
131
132 void display(void)
133 {
134         update();
135
136         vox_render(vox);
137         vox_sky_grad(vox, COLOR_HORIZON, COLOR_ZENITH);
138
139         glfb_update(fb);
140         glfb_display();
141
142         glutSwapBuffers();
143         assert(glGetError() == GL_NO_ERROR);
144
145         if(mbstate[0]) {
146                 mwarp = 1;
147                 glutWarpPointer(win_width / 2, win_height / 2);
148         }
149 }
150
151 void idle(void)
152 {
153         glutPostRedisplay();
154 }
155
156 void reshape(int x, int y)
157 {
158         glViewport(0, 0, x, y);
159
160         win_width = x;
161         win_height = y;
162 }
163
164 void keyb(unsigned char key, int x, int y)
165 {
166         switch(key) {
167         case 27:
168                 exit(0);
169
170         case 'w':
171                 input |= INP_FWD;
172                 break;
173         case 's':
174                 input |= INP_BACK;
175                 break;
176         case 'a':
177                 input |= INP_LEFT;
178                 break;
179         case 'd':
180                 input |= INP_RIGHT;
181                 break;
182         case 'q':
183                 input |= INP_LTURN;
184                 break;
185         case 'e':
186                 input |= INP_RTURN;
187                 break;
188
189         case 'h':
190                 hfilt ^= 1;
191                 printf("filtering: height(%s) color(%s)\n", hfilt ? "linear" : "nearest",
192                                 cfilt ? "linear" : "nearest");
193                 vox_filter(vox, hfilt, cfilt);
194                 break;
195
196         case 'c':
197                 cfilt ^= 1;
198                 vox_filter(vox, hfilt, cfilt);
199                 printf("filtering: height(%s) color(%s)\n", hfilt ? "linear" : "nearest",
200                                 cfilt ? "linear" : "nearest");
201                 break;
202
203         default:
204                 break;
205         }
206 }
207
208 void keyb_up(unsigned char key, int x, int y)
209 {
210         switch(key) {
211         case 'w':
212                 input &= ~INP_FWD;
213                 break;
214         case 's':
215                 input &= ~INP_BACK;
216                 break;
217         case 'a':
218                 input &= ~INP_LEFT;
219                 break;
220         case 'd':
221                 input &= ~INP_RIGHT;
222                 break;
223         case 'q':
224                 input &= ~INP_LTURN;
225                 break;
226         case 'e':
227                 input &= ~INP_RTURN;
228                 break;
229
230         default:
231                 break;
232         }
233 }
234
235 void mouse(int bn, int st, int x, int y)
236 {
237         int bidx = bn - GLUT_LEFT_BUTTON;
238
239         if(bidx < 3) {
240                 mbstate[bidx] = st == GLUT_DOWN;
241         }
242         mouse_x = x;
243         mouse_y = y;
244
245         if(st == GLUT_DOWN) {
246                 glutSetCursor(GLUT_CURSOR_NONE);
247         } else {
248                 glutSetCursor(GLUT_CURSOR_LEFT_ARROW);
249         }
250 }
251
252 void motion(int x, int y)
253 {
254         int dx = x - mouse_x;
255         int dy = y - mouse_y;
256         mouse_x = x;
257         mouse_y = y;
258
259         if(mwarp) {
260                 mwarp = 0;
261                 return;
262         }
263         if(!(dx | dy)) return;
264
265         if(mbstate[0]) {
266                 angle -= dx << 6;
267         }
268 }