gpuray_glsl

diff src/main.cc @ 0:f234630e38ff

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 09 Nov 2014 13:03:36 +0200
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/main.cc	Sun Nov 09 13:03:36 2014 +0200
     1.3 @@ -0,0 +1,396 @@
     1.4 +#include <stdio.h>
     1.5 +#include <stdlib.h>
     1.6 +#include <stdarg.h>
     1.7 +#include <assert.h>
     1.8 +#include "opengl.h"
     1.9 +
    1.10 +#include "gpuscene.h"
    1.11 +#include "sphere.h"
    1.12 +#include "plane.h"
    1.13 +#include "image.h"
    1.14 +#include "rend.h"
    1.15 +#include "glsdr.h"
    1.16 +
    1.17 +static bool init(const char *scene_fname);
    1.18 +static void cleanup();
    1.19 +static void disp();
    1.20 +static void draw_text(float r, float g, float b, const char *fmt, ...);
    1.21 +//static void update_texture(const float *fb);
    1.22 +static void idle();
    1.23 +static void reshape(int x, int y);
    1.24 +static void handle_keys(float dt);
    1.25 +static void keyb(unsigned char key, int x, int y);
    1.26 +static void keyb_up(unsigned char key, int x, int y);
    1.27 +static void skeyb(int key, int x, int y);
    1.28 +static void mouse(int bn, int st, int x, int y);
    1.29 +static void motion(int x, int y);
    1.30 +static void sball_motion(int x, int y, int z);
    1.31 +static void sball_rotate(int x, int y, int z);
    1.32 +static void sball_button(int bn, int state);
    1.33 +
    1.34 +static unsigned int tex;
    1.35 +static long last_fps_upd, first_time = -1;
    1.36 +static long frames, total_frames;
    1.37 +static float fps;
    1.38 +static int xsz = 800;
    1.39 +static int ysz = 450;
    1.40 +//static int tex_xsz, tex_ysz;
    1.41 +
    1.42 +static GPUScene *scn;
    1.43 +static FlyCamera *cam;
    1.44 +
    1.45 +static float img_scale = 1.0f;
    1.46 +static bool keystate[256];
    1.47 +
    1.48 +static char *scene_fname;
    1.49 +static bool sdr_valid = true;
    1.50 +
    1.51 +int main(int argc, char **argv)
    1.52 +{
    1.53 +	glutInit(&argc, argv);
    1.54 +
    1.55 +	int num_samples = 1;
    1.56 +
    1.57 +	for(int i=1; i<argc; i++) {
    1.58 +		if(argv[i][0] == '-') {
    1.59 +			if(strcmp(argv[i], "-size") == 0) {
    1.60 +				if(sscanf(argv[++i], "%dx%d", &xsz, &ysz) < 2) {
    1.61 +					fprintf(stderr, "-size must be followed by the image resolution (WxH)\n");
    1.62 +					return 1;
    1.63 +				}
    1.64 +
    1.65 +			} else if(strcmp(argv[i], "-samples") == 0) {
    1.66 +				num_samples = atoi(argv[++i]);
    1.67 +				if(num_samples <= 0) {
    1.68 +					fprintf(stderr, "-samples must be followed by the number of samples per pixel\n");
    1.69 +					return 1;
    1.70 +				}
    1.71 +			} else if(strcmp(argv[i], "-scale") == 0) {
    1.72 +				img_scale = atof(argv[++i]);
    1.73 +				if(img_scale <= 1.0f) {
    1.74 +					fprintf(stderr, "-scale must be followed by an image scale factor >= 1\n");
    1.75 +					return 1;
    1.76 +				}
    1.77 +			} else {
    1.78 +				fprintf(stderr, "invalid option: %s\n", argv[i]);
    1.79 +				return 1;
    1.80 +			}
    1.81 +		} else {
    1.82 +			if(scene_fname) {
    1.83 +				fprintf(stderr, "unexpected argument: %s\n", argv[i]);
    1.84 +				return 1;
    1.85 +			}
    1.86 +			scene_fname = argv[i];
    1.87 +		}
    1.88 +	}
    1.89 +
    1.90 +	glutInitWindowSize(xsz * img_scale, ysz * img_scale);
    1.91 +	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
    1.92 +	glutCreateWindow("single threaded");
    1.93 +
    1.94 +	glutDisplayFunc(disp);
    1.95 +	glutIdleFunc(idle);
    1.96 +	glutReshapeFunc(reshape);
    1.97 +	glutKeyboardFunc(keyb);
    1.98 +	glutKeyboardUpFunc(keyb_up);
    1.99 +	glutSpecialFunc(skeyb);
   1.100 +	glutMouseFunc(mouse);
   1.101 +	glutMotionFunc(motion);
   1.102 +	glutSpaceballMotionFunc(sball_motion);
   1.103 +	glutSpaceballRotateFunc(sball_rotate);
   1.104 +	glutSpaceballButtonFunc(sball_button);
   1.105 +
   1.106 +	glewInit();
   1.107 +
   1.108 +	if(!init(scene_fname)) {
   1.109 +		return 1;
   1.110 +	}
   1.111 +	atexit(cleanup);
   1.112 +
   1.113 +	glutMainLoop();
   1.114 +	return 0;
   1.115 +}
   1.116 +
   1.117 +static bool init(const char *scene_fname)
   1.118 +{
   1.119 +	scn = new GPUScene;
   1.120 +	if(!scn->load(scene_fname ? scene_fname : "scene")) {
   1.121 +		return false;
   1.122 +	}
   1.123 +
   1.124 +	cam = new FlyCamera;
   1.125 +	cam->input_move(0, 1.5, -10);
   1.126 +	cam->input_rotate(25, 0, 0);
   1.127 +	scn->set_camera(cam);
   1.128 +
   1.129 +	if(!init_renderer(scn, xsz, ysz)) {
   1.130 +		return false;
   1.131 +	}
   1.132 +
   1.133 +	glGenTextures(1, &tex);
   1.134 +	glBindTexture(GL_TEXTURE_2D, tex);
   1.135 +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   1.136 +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   1.137 +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
   1.138 +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
   1.139 +
   1.140 +	int srgb_capable;
   1.141 +	if(GLEW_EXT_framebuffer_sRGB && (glGetIntegerv(GL_FRAMEBUFFER_SRGB_CAPABLE_EXT, &srgb_capable), srgb_capable)) {
   1.142 +		printf("enabling sRGB framebuffer\n");
   1.143 +		glEnable(GL_FRAMEBUFFER_SRGB);
   1.144 +	} else {
   1.145 +		printf("using post shader for gamma correction\n");
   1.146 +		unsigned int post_sdr = create_program_load(0, "sdr/postsdr.glsl");
   1.147 +		if(post_sdr) {
   1.148 +			glUseProgram(post_sdr);
   1.149 +		}
   1.150 +	}
   1.151 +
   1.152 +	last_fps_upd = glutGet(GLUT_ELAPSED_TIME);
   1.153 +	first_time = last_fps_upd;
   1.154 +	total_frames = 0;
   1.155 +	return true;
   1.156 +}
   1.157 +
   1.158 +static void cleanup()
   1.159 +{
   1.160 +	long interval = glutGet(GLUT_ELAPSED_TIME) - first_time;
   1.161 +	printf("average fps: %.2f\n", (float)total_frames / ((float)interval / 1000.0f));
   1.162 +
   1.163 +	glDeleteTextures(1, &tex);
   1.164 +
   1.165 +	destroy_renderer();
   1.166 +	delete scn;
   1.167 +}
   1.168 +
   1.169 +static void disp()
   1.170 +{
   1.171 +	static long prev_msec;
   1.172 +	long interval, msec = glutGet(GLUT_ELAPSED_TIME);
   1.173 +
   1.174 +	handle_keys((msec - prev_msec) / 1000.0f);
   1.175 +	prev_msec = msec;
   1.176 +
   1.177 +	//update_texture();
   1.178 +	if(sdr_valid) {
   1.179 +		render_frame(msec);
   1.180 +	} else {
   1.181 +		glUseProgram(0);
   1.182 +		glMatrixMode(GL_MODELVIEW);
   1.183 +		glLoadIdentity();
   1.184 +		glMatrixMode(GL_PROJECTION);
   1.185 +		glLoadIdentity();
   1.186 +
   1.187 +		glLineWidth(8.0);
   1.188 +		glBegin(GL_LINES);
   1.189 +		glColor3f(1, 0, 0);
   1.190 +		glVertex2f(-1, -1);
   1.191 +		glVertex2f(1, 1);
   1.192 +		glVertex2f(-1, 1);
   1.193 +		glVertex2f(1, -1);
   1.194 +		glEnd();
   1.195 +		glLineWidth(1.0);
   1.196 +	}
   1.197 +
   1.198 +	draw_text(0.8, 0.75, 0, "fps: %.2f", fps);
   1.199 +
   1.200 +	glutSwapBuffers();
   1.201 +	frames++;
   1.202 +	total_frames++;
   1.203 +
   1.204 +	interval = (msec = glutGet(GLUT_ELAPSED_TIME)) - last_fps_upd;
   1.205 +	if(interval >= 2000) {
   1.206 +		float tm = (float)interval / 1000.0f;
   1.207 +		fps = (float)frames / tm;
   1.208 +		/*printf("%.2f fps         \r", (float)frames / tm);
   1.209 +		fflush(stdout);*/
   1.210 +		last_fps_upd = msec;
   1.211 +		frames = 0;
   1.212 +	}
   1.213 +}
   1.214 +
   1.215 +void draw_text(float r, float g, float b, const char *fmt, ...)
   1.216 +{
   1.217 +	char buf[256], *text = buf;
   1.218 +	va_list ap;
   1.219 +
   1.220 +	va_start(ap, fmt);
   1.221 +	vsprintf(buf, fmt, ap);
   1.222 +	va_end(ap);
   1.223 +
   1.224 +	glUseProgram(0);
   1.225 +
   1.226 +	glMatrixMode(GL_MODELVIEW);
   1.227 +	glPushMatrix();
   1.228 +	glLoadIdentity();
   1.229 +	glMatrixMode(GL_PROJECTION);
   1.230 +	glPushMatrix();
   1.231 +	glLoadIdentity();
   1.232 +	glOrtho(0, xsz, 0, ysz, -1, 1);
   1.233 +
   1.234 +	glColor3f(r, g, b);
   1.235 +	glRasterPos2f(2, 4);
   1.236 +	while(*text) {
   1.237 +		glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *text++);
   1.238 +	}
   1.239 +	glColor3f(1, 1, 1);
   1.240 +
   1.241 +	glPopMatrix();
   1.242 +	glMatrixMode(GL_MODELVIEW);
   1.243 +	glPopMatrix();
   1.244 +}
   1.245 +
   1.246 +
   1.247 +/*
   1.248 +static void update_texture()
   1.249 +{
   1.250 +	int ntx = next_pow2(xsz);
   1.251 +	int nty = next_pow2(ysz);
   1.252 +
   1.253 +	if(ntx != tex_xsz || nty != tex_ysz) {
   1.254 +		tex_xsz = ntx;
   1.255 +		tex_ysz = nty;
   1.256 +
   1.257 +		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, tex_xsz, tex_ysz, 0, GL_RGB, GL_FLOAT, 0);
   1.258 +	}
   1.259 +}
   1.260 +*/
   1.261 +
   1.262 +static void idle()
   1.263 +{
   1.264 +	glutPostRedisplay();
   1.265 +}
   1.266 +
   1.267 +static void reshape(int x, int y)
   1.268 +{
   1.269 +	int tx, ty;
   1.270 +
   1.271 +	xsz = x / img_scale;
   1.272 +	ysz = y / img_scale;
   1.273 +
   1.274 +	glViewport(0, 0, x, y);
   1.275 +
   1.276 +	/* setup the texture matrix that maps just the visible area
   1.277 +	 * of the texture to [0, 1]
   1.278 +	 */
   1.279 +	tx = next_pow2(xsz);
   1.280 +	ty = next_pow2(ysz);
   1.281 +
   1.282 +	glMatrixMode(GL_TEXTURE);
   1.283 +	glLoadIdentity();
   1.284 +	glScalef((float)xsz / tx, (float)ysz / ty, 1.0f);
   1.285 +
   1.286 +	resize_renderer(xsz, ysz);
   1.287 +}
   1.288 +
   1.289 +static void handle_keys(float dt)
   1.290 +{
   1.291 +	Vector3 move;
   1.292 +	float tilt = 0.0f;
   1.293 +	float offs = dt * 8.0;
   1.294 +
   1.295 +	if(keystate['w']) {
   1.296 +		move.z += offs;
   1.297 +	}
   1.298 +	if(keystate['s']) {
   1.299 +		move.z -= offs;
   1.300 +	}
   1.301 +	if(keystate['d']) {
   1.302 +		move.x += offs;
   1.303 +	}
   1.304 +	if(keystate['a']) {
   1.305 +		move.x -= offs;
   1.306 +	}
   1.307 +
   1.308 +	if(keystate['q']) {
   1.309 +		tilt -= dt;
   1.310 +	}
   1.311 +	if(keystate['e']) {
   1.312 +		tilt += dt;
   1.313 +	}
   1.314 +
   1.315 +	cam->input_move(move.x, move.y, move.z);
   1.316 +	cam->input_rotate(0, 0, tilt);
   1.317 +}
   1.318 +
   1.319 +static void keyb(unsigned char key, int x, int y)
   1.320 +{
   1.321 +	keystate[key] = true;
   1.322 +
   1.323 +	switch(key) {
   1.324 +	case 27:
   1.325 +		exit(0);
   1.326 +
   1.327 +	case '`':
   1.328 +		sdr_valid = reload_shader();
   1.329 +		break;
   1.330 +	}
   1.331 +}
   1.332 +
   1.333 +static void keyb_up(unsigned char key, int x, int y)
   1.334 +{
   1.335 +	keystate[key] = false;
   1.336 +}
   1.337 +
   1.338 +static void skeyb(int key, int x, int y)
   1.339 +{
   1.340 +	switch(key) {
   1.341 +	case GLUT_KEY_F1:
   1.342 +		printf("reinitializing\n");
   1.343 +		cleanup();
   1.344 +		sdr_valid = init(scene_fname);
   1.345 +		break;
   1.346 +
   1.347 +	default:
   1.348 +		break;
   1.349 +	}
   1.350 +}
   1.351 +
   1.352 +static int prev_x, prev_y;
   1.353 +
   1.354 +static void mouse(int bn, int st, int x, int y)
   1.355 +{
   1.356 +	prev_x = x;
   1.357 +	prev_y = y;
   1.358 +}
   1.359 +
   1.360 +static void motion(int x, int y)
   1.361 +{
   1.362 +	int dx = x - prev_x;
   1.363 +	int dy = y - prev_y;
   1.364 +	prev_x = x;
   1.365 +	prev_y = y;
   1.366 +	cam->input_rotate(-dy * 0.01, -dx * 0.01,  0);
   1.367 +}
   1.368 +
   1.369 +static void sball_motion(int x, int y, int z)
   1.370 +{
   1.371 +	float fx = x * 0.01;
   1.372 +	float fy = y * 0.01;
   1.373 +	float fz = z * 0.01;
   1.374 +	cam->input_move(fx, fy, fz);
   1.375 +}
   1.376 +
   1.377 +static void sball_rotate(int x, int y, int z)
   1.378 +{
   1.379 +	float fx = x * 0.00025;
   1.380 +	float fy = y * 0.00025;
   1.381 +	float fz = z * 0.00025;
   1.382 +	cam->input_rotate(fx, fy, fz);
   1.383 +}
   1.384 +
   1.385 +static void sball_button(int bn, int state)
   1.386 +{
   1.387 +}
   1.388 +
   1.389 +
   1.390 +int next_pow2(int x)
   1.391 +{
   1.392 +	x--;
   1.393 +	x = (x >> 1) | x;
   1.394 +	x = (x >> 2) | x;
   1.395 +	x = (x >> 4) | x;
   1.396 +	x = (x >> 8) | x;
   1.397 +	x = (x >> 16) | x;
   1.398 +	return x + 1;
   1.399 +}