5 #include "cgmath/cgmath.h"
12 static int ginit(void);
13 static void gdestroy(void);
14 static int gstart(void);
15 static void gstop(void);
16 static void gdisplay(void);
17 static void greshape(int x, int y);
18 static void gkeyb(int key, int press);
19 static void gmouse(int bn, int press, int x, int y);
20 static void gmotion(int x, int y);
22 struct game_screen scr_game = {
27 gkeyb, gmouse, gmotion
30 static struct level *lvl;
32 static float proj_mat[16], view_mat[16];
34 static float cam_theta, cam_phi, cam_dist;
35 static cgm_vec3 cam_pan;
37 static unsigned int sdr;
39 static int rbuf_width, rbuf_height;
40 static unsigned int fbo, rbuf_col, rbuf_zbuf;
43 static int ginit(void)
48 static void gdestroy(void)
50 glDeleteRenderbuffers(1, &rbuf_col);
51 glDeleteRenderbuffers(1, &rbuf_zbuf);
52 glDeleteFramebuffers(1, &fbo);
55 static int gstart(void)
57 lvl = malloc_nf(sizeof *lvl);
59 if(load_level(lvl, "data/test.lvl") == -1) {
62 cam_pan.x = -lvl->sx * lvl->scale;
64 cam_pan.z = -lvl->sy * lvl->scale;
66 glEnable(GL_DEPTH_TEST);
69 add_shader_footer(GL_FRAGMENT_SHADER, lvl->sdf_src);
71 add_shader_header(GL_FRAGMENT_SHADER, "#define TEST_SDF\n");
73 if(!(sdr = create_program_load("sdr/raydungeon.v.glsl", "sdr/raydungeon.p.glsl"))) {
76 clear_shader_footer(GL_FRAGMENT_SHADER);
81 static void gstop(void)
89 static void gdisplay(void)
93 struct level_cell *cell;
95 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
96 glViewport(0, 0, rbuf_width, rbuf_height);
98 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
100 cgm_mtranslation(view_mat, 0, 0, -cam_dist);
101 cgm_mprerotate_x(view_mat, cam_phi);
102 cgm_mprerotate_y(view_mat, cam_theta);
103 cgm_mpretranslate(view_mat, cam_pan.x, cam_pan.y, cam_pan.z);
104 glMatrixMode(GL_MODELVIEW);
105 glLoadMatrixf(view_mat);
109 glBegin(GL_TRIANGLES);
110 glTexCoord2f(0, 0); glVertex2f(-1, -1);
111 glTexCoord2f(2, 0); glVertex2f(3, -1);
112 glTexCoord2f(0, 2); glVertex2f(-1, 3);
122 for(i=0; i<lvl->ysz; i++) {
123 y = (float)i * lvl->scale;
124 for(j=0; j<lvl->xsz; j++) {
125 x = (float)j * lvl->scale;
127 glVertex3f(x - 0.48 * lvl->scale, -1, y - 0.48 * lvl->scale);
128 glVertex3f(x + 0.48 * lvl->scale, -1, y - 0.48 * lvl->scale);
129 glVertex3f(x + 0.48 * lvl->scale, -1, y + 0.48 * lvl->scale);
130 glVertex3f(x - 0.48 * lvl->scale, -1, y + 0.48 * lvl->scale);
137 glViewport(0, 0, win_width, win_height);
138 glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
139 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
140 glBlitFramebuffer(0, 0, rbuf_width, rbuf_height, 0, 0, win_width, win_height,
141 GL_COLOR_BUFFER_BIT, GL_NEAREST);
142 glBindFramebuffer(GL_FRAMEBUFFER, 0);
145 static void greshape(int x, int y)
147 cgm_mperspective(proj_mat, cgm_deg_to_rad(60), win_aspect, 0.5, 200.0);
148 glMatrixMode(GL_PROJECTION);
149 glLoadMatrixf(proj_mat);
151 rbuf_width = ((int)(x * opt.gfx.render_res) + 3) & 0xfffffc;
152 rbuf_height = ((int)(y * opt.gfx.render_res) + 3) & 0xfffffc;
153 printf("render buffer %dx%d\n", rbuf_width, rbuf_height);
156 glGenFramebuffers(1, &fbo);
157 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
159 glGenRenderbuffers(1, &rbuf_col);
160 glBindRenderbuffer(GL_RENDERBUFFER, rbuf_col);
161 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, rbuf_width, rbuf_height);
162 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbuf_col);
164 glGenRenderbuffers(1, &rbuf_zbuf);
165 glBindRenderbuffer(GL_RENDERBUFFER, rbuf_zbuf);
166 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, rbuf_width, rbuf_height);
167 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbuf_zbuf);
169 glBindFramebuffer(GL_FRAMEBUFFER, 0);
171 glBindRenderbuffer(GL_RENDERBUFFER, rbuf_col);
172 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, rbuf_width, rbuf_height);
174 glBindRenderbuffer(GL_RENDERBUFFER, rbuf_zbuf);
175 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, rbuf_width, rbuf_height);
179 static void gkeyb(int key, int press)
185 game_grabmouse(-1); /* toggle */
195 static void gmouse(int bn, int press, int x, int y)
199 static void gmotion(int x, int y)
201 int dx = x - mouse_x;
202 int dy = y - mouse_y;
204 if(!(dx | dy)) return;
207 cam_theta += dx * 0.02;
208 cam_phi += dy * 0.02;
209 if(cam_phi < -M_PI/2) cam_phi = -M_PI/2;
210 if(cam_phi > M_PI/2) cam_phi = M_PI/2;
213 float up[3], right[3];
215 up[0] = -sin(cam_theta) * sin(cam_phi);
216 up[1] = -cos(cam_phi);
217 up[2] = cos(cam_theta) * sin(cam_phi);
218 right[0] = cos(cam_theta);
220 right[2] = sin(cam_theta);
222 cam_pan.x += (right[0] * dx + up[0] * dy) * 0.01;
223 cam_pan.y += up[1] * dy * 0.01;
224 cam_pan.z += (right[2] * dx + up[2] * dy) * 0.01;
227 cam_dist += dy * 0.01;
228 if(cam_dist < 0) cam_dist = 0;