# HG changeset patch # User John Tsiombikas # Date 1405646693 -10800 # Node ID e9ab4861536d11c0c38b722d8c85fe04a8c9964a # Parent 977bc1cb055b8ec7438f839570928f6923071f8a added glow diff -r 977bc1cb055b -r e9ab4861536d src/main.cc --- a/src/main.cc Fri Jul 18 02:35:06 2014 +0300 +++ b/src/main.cc Fri Jul 18 04:24:53 2014 +0300 @@ -10,14 +10,25 @@ #include #include "dev.h" #include "scene.h" +#include "timer.h" +#include "fblur.h" + + +enum { + REGULAR_PASS, + GLOW_PASS +}; static bool init(); static void cleanup(); static void display(); +static void draw_scene(int pass = REGULAR_PASS); +static void post_glow(void); static void keyb(int key, bool pressed); static void mouse(int bn, bool pressed, int x, int y); static void motion(int x, int y); static Ray calc_pick_ray(int x, int y); +static int next_pow2(int x); static Window create_window(const char *title, int xsz, int ysz); static void process_events(); @@ -48,6 +59,15 @@ static Object *led_obj[2]; static Vector3 led_on_emissive; +static bool opt_use_glow = true; +#define GLOW_SZ_DIV 3 +static unsigned int glow_tex; +static int glow_tex_xsz, glow_tex_ysz, glow_xsz, glow_ysz; +static int glow_iter = 1; +static int blur_size = 5; +unsigned char *glow_framebuf; + + int main(int argc, char **argv) { if(proc_args(argc, argv) == -1) { @@ -82,8 +102,8 @@ } if(draw_pending) { + draw_pending = false; display(); - draw_pending = false; } } return 0; @@ -102,7 +122,7 @@ return false; } - if(!(win = create_window("equeue device emulator", 800, 600))) { + if(!(win = create_window("equeue device emulator", 512, 512))) { return false; } @@ -143,6 +163,13 @@ scn->remove_object(led_obj[1]); led_on_emissive = led_obj[0]->mtl.emissive; + // create the glow texture + glGenTextures(1, &glow_tex); + glBindTexture(GL_TEXTURE_2D, glow_tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glEnable(GL_LIGHTING); @@ -168,11 +195,10 @@ } #define DIGIT_USZ (1.0 / 11.0) +#define MIN_REDRAW_INTERVAL (1000 / 40) /* 40fps */ static void display() { - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0, 0, -cam_dist); @@ -182,10 +208,60 @@ float lpos[] = {-7, 5, 10, 0}; glLightfv(GL_LIGHT0, GL_POSITION, lpos); - scn->render(); + if(opt_use_glow) { + glViewport(0, 0, glow_xsz, glow_ysz); + + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + draw_scene(GLOW_PASS); + + glReadPixels(0, 0, glow_xsz, glow_ysz, GL_RGBA, GL_UNSIGNED_BYTE, glow_framebuf); + glViewport(0, 0, win_width, win_height); + } + + glClearColor(0.05, 0.05, 0.05, 1); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + draw_scene(); + + if(opt_use_glow) { + for(int i=0; irender(); + } // shift the textures and modify the materials to make the display match our state for(int i=0; i<2; i++) { + // 7seg int digit = get_display_number(); for(int j=0; jrender(); } +} - glXSwapBuffers(dpy, win); - assert(glGetError() == GL_NO_ERROR); +static void post_glow(void) +{ + float max_s = (float)glow_xsz / (float)glow_tex_xsz; + float max_t = (float)glow_ysz / (float)glow_tex_ysz; + + glPushAttrib(GL_ENABLE_BIT); + + glBlendFunc(GL_ONE, GL_ONE); + glEnable(GL_BLEND); + glDisable(GL_CULL_FACE); + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, glow_tex); + + glBegin(GL_QUADS); + glColor4f(1, 1, 1, 1); + glTexCoord2f(0, 0); + glVertex2f(-1, -1); + glTexCoord2f(max_s, 0); + glVertex2f(1, -1); + glTexCoord2f(max_s, max_t); + glVertex2f(1, 1); + glTexCoord2f(0, max_t); + glVertex2f(-1, 1); + glEnd(); + + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + glPopAttrib(); } + static void reshape(int x, int y) { glViewport(0, 0, x, y); @@ -220,6 +336,20 @@ win_width = x; win_height = y; + + if(opt_use_glow) { + glow_xsz = x / GLOW_SZ_DIV; + glow_ysz = y / GLOW_SZ_DIV; + printf("glow image size: %dx%d\n", glow_xsz, glow_ysz); + + delete [] glow_framebuf; + glow_framebuf = new unsigned char[glow_xsz * glow_ysz * 4]; + + glow_tex_xsz = next_pow2(glow_xsz); + glow_tex_ysz = next_pow2(glow_ysz); + glBindTexture(GL_TEXTURE_2D, glow_tex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glow_tex_xsz, glow_tex_ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + } } static void keyb(int key, bool pressed) @@ -320,6 +450,17 @@ return ray; } +static int next_pow2(int x) +{ + x--; + x = (x >> 1) | x; + x = (x >> 2) | x; + x = (x >> 4) | x; + x = (x >> 8) | x; + x = (x >> 16) | x; + return x + 1; +} + static Window create_window(const char *title, int xsz, int ysz) { int scr = DefaultScreen(dpy); diff -r 977bc1cb055b -r e9ab4861536d src/material.cc --- a/src/material.cc Fri Jul 18 02:35:06 2014 +0300 +++ b/src/material.cc Fri Jul 18 04:24:53 2014 +0300 @@ -72,9 +72,11 @@ } + glMatrixMode(GL_TEXTURE); for(int i=num_tex; i<4; i++) { glActiveTexture(GL_TEXTURE0 + i); glDisable(GL_TEXTURE_2D); + glLoadIdentity(); } glActiveTexture(GL_TEXTURE0); diff -r 977bc1cb055b -r e9ab4861536d src/timer.cc --- a/src/timer.cc Fri Jul 18 02:35:06 2014 +0300 +++ b/src/timer.cc Fri Jul 18 04:24:53 2014 +0300 @@ -13,3 +13,8 @@ } return (tv.tv_sec - tv0.tv_sec) * 1000 + (tv.tv_usec - tv0.tv_usec) / 1000; } + +void wait_for(unsigned long msec) +{ + usleep(msec * 1000); +} diff -r 977bc1cb055b -r e9ab4861536d src/timer.h --- a/src/timer.h Fri Jul 18 02:35:06 2014 +0300 +++ b/src/timer.h Fri Jul 18 04:24:53 2014 +0300 @@ -2,5 +2,6 @@ #define TIMER_H_ unsigned long get_msec(); +void wait_for(unsigned long msec); #endif /* TIMER_H_ */