eqemu
changeset 7:e9ab4861536d
added glow
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Fri, 18 Jul 2014 04:24:53 +0300 |
parents | 977bc1cb055b |
children | c3b48cb2797f |
files | src/main.cc src/material.cc src/timer.cc src/timer.h |
diffstat | 4 files changed, 156 insertions(+), 7 deletions(-) [+] |
line diff
1.1 --- a/src/main.cc Fri Jul 18 02:35:06 2014 +0300 1.2 +++ b/src/main.cc Fri Jul 18 04:24:53 2014 +0300 1.3 @@ -10,14 +10,25 @@ 1.4 #include <GL/glx.h> 1.5 #include "dev.h" 1.6 #include "scene.h" 1.7 +#include "timer.h" 1.8 +#include "fblur.h" 1.9 + 1.10 + 1.11 +enum { 1.12 + REGULAR_PASS, 1.13 + GLOW_PASS 1.14 +}; 1.15 1.16 static bool init(); 1.17 static void cleanup(); 1.18 static void display(); 1.19 +static void draw_scene(int pass = REGULAR_PASS); 1.20 +static void post_glow(void); 1.21 static void keyb(int key, bool pressed); 1.22 static void mouse(int bn, bool pressed, int x, int y); 1.23 static void motion(int x, int y); 1.24 static Ray calc_pick_ray(int x, int y); 1.25 +static int next_pow2(int x); 1.26 1.27 static Window create_window(const char *title, int xsz, int ysz); 1.28 static void process_events(); 1.29 @@ -48,6 +59,15 @@ 1.30 static Object *led_obj[2]; 1.31 static Vector3 led_on_emissive; 1.32 1.33 +static bool opt_use_glow = true; 1.34 +#define GLOW_SZ_DIV 3 1.35 +static unsigned int glow_tex; 1.36 +static int glow_tex_xsz, glow_tex_ysz, glow_xsz, glow_ysz; 1.37 +static int glow_iter = 1; 1.38 +static int blur_size = 5; 1.39 +unsigned char *glow_framebuf; 1.40 + 1.41 + 1.42 int main(int argc, char **argv) 1.43 { 1.44 if(proc_args(argc, argv) == -1) { 1.45 @@ -82,8 +102,8 @@ 1.46 } 1.47 1.48 if(draw_pending) { 1.49 + draw_pending = false; 1.50 display(); 1.51 - draw_pending = false; 1.52 } 1.53 } 1.54 return 0; 1.55 @@ -102,7 +122,7 @@ 1.56 return false; 1.57 } 1.58 1.59 - if(!(win = create_window("equeue device emulator", 800, 600))) { 1.60 + if(!(win = create_window("equeue device emulator", 512, 512))) { 1.61 return false; 1.62 } 1.63 1.64 @@ -143,6 +163,13 @@ 1.65 scn->remove_object(led_obj[1]); 1.66 led_on_emissive = led_obj[0]->mtl.emissive; 1.67 1.68 + // create the glow texture 1.69 + glGenTextures(1, &glow_tex); 1.70 + glBindTexture(GL_TEXTURE_2D, glow_tex); 1.71 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1.72 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 1.73 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); 1.74 + 1.75 glEnable(GL_DEPTH_TEST); 1.76 glEnable(GL_CULL_FACE); 1.77 glEnable(GL_LIGHTING); 1.78 @@ -168,11 +195,10 @@ 1.79 } 1.80 1.81 #define DIGIT_USZ (1.0 / 11.0) 1.82 +#define MIN_REDRAW_INTERVAL (1000 / 40) /* 40fps */ 1.83 1.84 static void display() 1.85 { 1.86 - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 1.87 - 1.88 glMatrixMode(GL_MODELVIEW); 1.89 glLoadIdentity(); 1.90 glTranslatef(0, 0, -cam_dist); 1.91 @@ -182,10 +208,60 @@ 1.92 float lpos[] = {-7, 5, 10, 0}; 1.93 glLightfv(GL_LIGHT0, GL_POSITION, lpos); 1.94 1.95 - scn->render(); 1.96 + if(opt_use_glow) { 1.97 + glViewport(0, 0, glow_xsz, glow_ysz); 1.98 + 1.99 + glClearColor(0, 0, 0, 1); 1.100 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 1.101 + 1.102 + draw_scene(GLOW_PASS); 1.103 + 1.104 + glReadPixels(0, 0, glow_xsz, glow_ysz, GL_RGBA, GL_UNSIGNED_BYTE, glow_framebuf); 1.105 + glViewport(0, 0, win_width, win_height); 1.106 + } 1.107 + 1.108 + glClearColor(0.05, 0.05, 0.05, 1); 1.109 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 1.110 + 1.111 + draw_scene(); 1.112 + 1.113 + if(opt_use_glow) { 1.114 + for(int i=0; i<glow_iter; i++) { 1.115 + fast_blur(BLUR_BOTH, blur_size, (uint32_t*)glow_framebuf, glow_xsz, glow_ysz); 1.116 + glBindTexture(GL_TEXTURE_2D, glow_tex); 1.117 + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, glow_xsz, glow_ysz, GL_RGBA, GL_UNSIGNED_BYTE, glow_framebuf); 1.118 + 1.119 + post_glow(); 1.120 + } 1.121 + } 1.122 + 1.123 + //if(get_led_state(0)) { 1.124 + // continuously redraw until the left LED times out 1.125 + draw_pending = true; 1.126 + //} 1.127 + 1.128 + glXSwapBuffers(dpy, win); 1.129 + assert(glGetError() == GL_NO_ERROR); 1.130 + 1.131 + /*static long prev_msec; 1.132 + long msec = get_msec(); 1.133 + long dt = msec - prev_msec; 1.134 + 1.135 + if(dt < MIN_REDRAW_INTERVAL) { 1.136 + wait_for(MIN_REDRAW_INTERVAL - dt); 1.137 + } 1.138 + prev_msec = get_msec();*/ 1.139 +} 1.140 + 1.141 +static void draw_scene(int pass) 1.142 +{ 1.143 + if(pass != GLOW_PASS) { 1.144 + scn->render(); 1.145 + } 1.146 1.147 // shift the textures and modify the materials to make the display match our state 1.148 for(int i=0; i<2; i++) { 1.149 + // 7seg 1.150 int digit = get_display_number(); 1.151 for(int j=0; j<i; j++) { 1.152 digit /= 10; 1.153 @@ -205,11 +281,51 @@ 1.154 } 1.155 led_obj[i]->render(); 1.156 } 1.157 +} 1.158 1.159 - glXSwapBuffers(dpy, win); 1.160 - assert(glGetError() == GL_NO_ERROR); 1.161 +static void post_glow(void) 1.162 +{ 1.163 + float max_s = (float)glow_xsz / (float)glow_tex_xsz; 1.164 + float max_t = (float)glow_ysz / (float)glow_tex_ysz; 1.165 + 1.166 + glPushAttrib(GL_ENABLE_BIT); 1.167 + 1.168 + glBlendFunc(GL_ONE, GL_ONE); 1.169 + glEnable(GL_BLEND); 1.170 + glDisable(GL_CULL_FACE); 1.171 + glDisable(GL_LIGHTING); 1.172 + glDisable(GL_DEPTH_TEST); 1.173 + 1.174 + glMatrixMode(GL_MODELVIEW); 1.175 + glPushMatrix(); 1.176 + glLoadIdentity(); 1.177 + glMatrixMode(GL_PROJECTION); 1.178 + glPushMatrix(); 1.179 + glLoadIdentity(); 1.180 + 1.181 + glEnable(GL_TEXTURE_2D); 1.182 + glBindTexture(GL_TEXTURE_2D, glow_tex); 1.183 + 1.184 + glBegin(GL_QUADS); 1.185 + glColor4f(1, 1, 1, 1); 1.186 + glTexCoord2f(0, 0); 1.187 + glVertex2f(-1, -1); 1.188 + glTexCoord2f(max_s, 0); 1.189 + glVertex2f(1, -1); 1.190 + glTexCoord2f(max_s, max_t); 1.191 + glVertex2f(1, 1); 1.192 + glTexCoord2f(0, max_t); 1.193 + glVertex2f(-1, 1); 1.194 + glEnd(); 1.195 + 1.196 + glPopMatrix(); 1.197 + glMatrixMode(GL_MODELVIEW); 1.198 + glPopMatrix(); 1.199 + 1.200 + glPopAttrib(); 1.201 } 1.202 1.203 + 1.204 static void reshape(int x, int y) 1.205 { 1.206 glViewport(0, 0, x, y); 1.207 @@ -220,6 +336,20 @@ 1.208 1.209 win_width = x; 1.210 win_height = y; 1.211 + 1.212 + if(opt_use_glow) { 1.213 + glow_xsz = x / GLOW_SZ_DIV; 1.214 + glow_ysz = y / GLOW_SZ_DIV; 1.215 + printf("glow image size: %dx%d\n", glow_xsz, glow_ysz); 1.216 + 1.217 + delete [] glow_framebuf; 1.218 + glow_framebuf = new unsigned char[glow_xsz * glow_ysz * 4]; 1.219 + 1.220 + glow_tex_xsz = next_pow2(glow_xsz); 1.221 + glow_tex_ysz = next_pow2(glow_ysz); 1.222 + glBindTexture(GL_TEXTURE_2D, glow_tex); 1.223 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glow_tex_xsz, glow_tex_ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); 1.224 + } 1.225 } 1.226 1.227 static void keyb(int key, bool pressed) 1.228 @@ -320,6 +450,17 @@ 1.229 return ray; 1.230 } 1.231 1.232 +static int next_pow2(int x) 1.233 +{ 1.234 + x--; 1.235 + x = (x >> 1) | x; 1.236 + x = (x >> 2) | x; 1.237 + x = (x >> 4) | x; 1.238 + x = (x >> 8) | x; 1.239 + x = (x >> 16) | x; 1.240 + return x + 1; 1.241 +} 1.242 + 1.243 static Window create_window(const char *title, int xsz, int ysz) 1.244 { 1.245 int scr = DefaultScreen(dpy);
2.1 --- a/src/material.cc Fri Jul 18 02:35:06 2014 +0300 2.2 +++ b/src/material.cc Fri Jul 18 04:24:53 2014 +0300 2.3 @@ -72,9 +72,11 @@ 2.4 } 2.5 2.6 2.7 + glMatrixMode(GL_TEXTURE); 2.8 for(int i=num_tex; i<4; i++) { 2.9 glActiveTexture(GL_TEXTURE0 + i); 2.10 glDisable(GL_TEXTURE_2D); 2.11 + glLoadIdentity(); 2.12 } 2.13 2.14 glActiveTexture(GL_TEXTURE0);
3.1 --- a/src/timer.cc Fri Jul 18 02:35:06 2014 +0300 3.2 +++ b/src/timer.cc Fri Jul 18 04:24:53 2014 +0300 3.3 @@ -13,3 +13,8 @@ 3.4 } 3.5 return (tv.tv_sec - tv0.tv_sec) * 1000 + (tv.tv_usec - tv0.tv_usec) / 1000; 3.6 } 3.7 + 3.8 +void wait_for(unsigned long msec) 3.9 +{ 3.10 + usleep(msec * 1000); 3.11 +}