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 +}
     4.1 --- a/src/timer.h	Fri Jul 18 02:35:06 2014 +0300
     4.2 +++ b/src/timer.h	Fri Jul 18 04:24:53 2014 +0300
     4.3 @@ -2,5 +2,6 @@
     4.4  #define TIMER_H_
     4.5  
     4.6  unsigned long get_msec();
     4.7 +void wait_for(unsigned long msec);
     4.8  
     4.9  #endif	/* TIMER_H_ */