conworlds

changeset 7:bd8202d6d28d

some progress...
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 22 Aug 2014 16:55:16 +0300
parents 3c36bc28c6c2
children 90abf4b93cc9
files src/game.cc src/game.h src/main.cc src/texture.cc src/texture.h src/vr/opt.c src/vr/opt.h src/vr/rbtree.c src/vr/rbtree.h src/vr/vr.c src/vr/vr.h src/vr/vr_impl.h src/vr/vr_libovr.c src/vr/vr_null.c vrchess.vcxproj vrchess.vcxproj.filters
diffstat 16 files changed, 1122 insertions(+), 60 deletions(-) [+]
line diff
     1.1 --- a/src/game.cc	Thu Aug 21 01:08:03 2014 +0300
     1.2 +++ b/src/game.cc	Fri Aug 22 16:55:16 2014 +0300
     1.3 @@ -4,11 +4,13 @@
     1.4  #include "texture.h"
     1.5  #include "vr/vr.h"
     1.6  
     1.7 +static void game_render_eye(int eye);
     1.8  static void draw_scene();
     1.9  static bool setup_rtarg(int x, int y);
    1.10  
    1.11 -static Texture *rtarg[2];
    1.12 +static Texture *rtarg;
    1.13  static unsigned int fbo, rtarg_depth;
    1.14 +static int rtwidth, rtheight;
    1.15  
    1.16  static const float move_speed = 10.0f;
    1.17  
    1.18 @@ -20,6 +22,7 @@
    1.19  bool game_init()
    1.20  {
    1.21  	vr_init();
    1.22 +	vr_use_module_named("null");
    1.23  
    1.24  	glEnable(GL_DEPTH_TEST);
    1.25  	glEnable(GL_CULL_FACE);
    1.26 @@ -45,8 +48,7 @@
    1.27  	if(fbo) {
    1.28  		glDeleteFramebuffers(1, &fbo);
    1.29  		glDeleteRenderbuffers(1, &rtarg_depth);
    1.30 -		delete rtarg[0];
    1.31 -		delete rtarg[1];
    1.32 +		delete rtarg;
    1.33  	}
    1.34  }
    1.35  
    1.36 @@ -83,22 +85,39 @@
    1.37  	cam.input_rotate(0, 0, roll);
    1.38  }
    1.39  
    1.40 -void game_render(int eye)
    1.41 +void game_render()
    1.42  {
    1.43 -	vr_begin(eye <= 0 ? VR_EYE_LEFT : VR_EYE_RIGHT);
    1.44 +	glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    1.45 +	glClearColor(1, 0, 0, 1);
    1.46 +	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    1.47  
    1.48 +	glViewport(0, 0, rtwidth / 2.0, rtheight);
    1.49 +	vr_begin(VR_EYE_LEFT);
    1.50 +	game_render_eye(-1);
    1.51 +	vr_end();
    1.52 +
    1.53 +	glViewport(rtwidth / 2, 0, rtwidth / 2.0, rtheight);
    1.54 +	vr_begin(VR_EYE_RIGHT);
    1.55 +	game_render_eye(1);
    1.56 +	vr_end();
    1.57 +
    1.58 +	glBindFramebuffer(GL_FRAMEBUFFER, 0);
    1.59 +	vr_output_texture(rtarg->get_texture_id(), 0, 0, (float)rtwidth / (float)rtarg->get_width(),
    1.60 +		(float)rtheight / (float)rtarg->get_height());
    1.61 +}
    1.62 +
    1.63 +static void game_render_eye(int eye)
    1.64 +{
    1.65  	float mat[16];
    1.66  	Matrix4x4 view_matrix = cam.get_matrix().inverse();
    1.67  
    1.68 -	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    1.69 -
    1.70  	glMatrixMode(GL_PROJECTION);
    1.71  	glLoadIdentity();
    1.72 -	if(eye == 0 || !vr_proj_matrix(eye < 0 ? 0 : 1, mat)) {
    1.73 +	//if(eye == 0 || !vr_proj_matrix(eye < 0 ? 0 : 1, 0.5, 500.0, mat)) {
    1.74  		gluPerspective(60.0, (float)fb_width / (float)fb_height, 0.5, 500.0);
    1.75 -	} else {
    1.76 -		glLoadTransposeMatrixf(mat);
    1.77 -	}
    1.78 +	/*} else {
    1.79 +		glLoadMatrixf(mat);
    1.80 +	}*/
    1.81  
    1.82  	glMatrixMode(GL_MODELVIEW);
    1.83  	if(eye == 0 || !vr_view_matrix(eye < 0 ? 0 : 1, mat)) {
    1.84 @@ -109,8 +128,6 @@
    1.85  	glMultTransposeMatrixf(view_matrix[0]);
    1.86  
    1.87  	draw_scene();
    1.88 -
    1.89 -	vr_end();
    1.90  }
    1.91  
    1.92  void game_reshape(int x, int y)
    1.93 @@ -119,7 +136,20 @@
    1.94  	fb_width = x;
    1.95  	fb_height = y;
    1.96  
    1.97 -	setup_rtarg(x, y);
    1.98 +	int lxres = vr_get_opti(VR_OPT_LEYE_XRES);
    1.99 +	if(lxres) {
   1.100 +		int lyres = vr_get_opti(VR_OPT_LEYE_YRES);
   1.101 +		int rxres = vr_get_opti(VR_OPT_REYE_XRES);
   1.102 +		int ryres = vr_get_opti(VR_OPT_REYE_YRES);
   1.103 +
   1.104 +		rtwidth = lxres + rxres;
   1.105 +		rtheight = lyres > ryres ? lyres : ryres;
   1.106 +	} else {
   1.107 +		rtwidth = x;
   1.108 +		rtheight = y;
   1.109 +	}
   1.110 +
   1.111 +	setup_rtarg(rtwidth, rtheight);
   1.112  }
   1.113  
   1.114  void game_keyboard(int key, bool pressed, int x, int y)
   1.115 @@ -222,10 +252,7 @@
   1.116  	if(!fbo) {
   1.117  		glGenFramebuffers(1, &fbo);
   1.118  		glGenRenderbuffers(1, &rtarg_depth);
   1.119 -
   1.120 -		for(int i=0; i<2; i++) {
   1.121 -			rtarg[i] = new Texture;
   1.122 -		}
   1.123 +		rtarg = new Texture;
   1.124  	}
   1.125  
   1.126  	glBindFramebuffer(GL_FRAMEBUFFER, fbo);
   1.127 @@ -234,17 +261,16 @@
   1.128  	glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, tex_width, tex_height);
   1.129  	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rtarg_depth);
   1.130  
   1.131 -	for(int i=0; i<2; i++) {
   1.132 -		rtarg[i] = new Texture;
   1.133 -		rtarg[i]->create2d(tex_width, tex_height);
   1.134 -		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
   1.135 -				GL_TEXTURE_2D, rtarg[i]->get_texture_id(), 0);
   1.136 -	}
   1.137 +	rtarg->create2d(tex_width, tex_height);
   1.138 +	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
   1.139 +		rtarg->get_texture_id(), 0);
   1.140  
   1.141  	if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
   1.142  		fprintf(stderr, "incomplete framebuffer!\n");
   1.143  		return false;
   1.144  	}
   1.145  	glBindFramebuffer(GL_FRAMEBUFFER, 0);
   1.146 +
   1.147 +	printf("created render target %dx%d (texture: %dx%d)\n", x, y, tex_width, tex_height);
   1.148  	return true;
   1.149  }
     2.1 --- a/src/game.h	Thu Aug 21 01:08:03 2014 +0300
     2.2 +++ b/src/game.h	Fri Aug 22 16:55:16 2014 +0300
     2.3 @@ -5,7 +5,7 @@
     2.4  void game_cleanup();
     2.5  
     2.6  void game_update(unsigned int msec);
     2.7 -void game_render(int eye);
     2.8 +void game_render();
     2.9  
    2.10  void game_reshape(int x, int y);
    2.11  void game_keyboard(int key, bool pressed, int x, int y);
     3.1 --- a/src/main.cc	Thu Aug 21 01:08:03 2014 +0300
     3.2 +++ b/src/main.cc	Fri Aug 22 16:55:16 2014 +0300
     3.3 @@ -50,6 +50,12 @@
     3.4  	if(!game_init()) {
     3.5  		return false;
     3.6  	}
     3.7 +
     3.8 +	int win_xsz = vr_get_opti(VR_OPT_DISPLAY_WIDTH);
     3.9 +	int win_ysz = vr_get_opti(VR_OPT_DISPLAY_HEIGHT);
    3.10 +	if(win_xsz && win_ysz) {
    3.11 +		glutReshapeWindow(win_xsz, win_ysz);
    3.12 +	}
    3.13  	return true;
    3.14  }
    3.15  
    3.16 @@ -63,7 +69,7 @@
    3.17  	unsigned int msec = glutGet(GLUT_ELAPSED_TIME);
    3.18  
    3.19  	game_update(msec);
    3.20 -	game_render(0);
    3.21 +	game_render();
    3.22  
    3.23  	if(!vr_swap_buffers()) {
    3.24  		glutSwapBuffers();
     4.1 --- a/src/texture.cc	Thu Aug 21 01:08:03 2014 +0300
     4.2 +++ b/src/texture.cc	Fri Aug 22 16:55:16 2014 +0300
     4.3 @@ -12,6 +12,16 @@
     4.4  	destroy();
     4.5  }
     4.6  
     4.7 +int Texture::get_width() const
     4.8 +{
     4.9 +	return img.get_width();
    4.10 +}
    4.11 +
    4.12 +int Texture::get_height() const
    4.13 +{
    4.14 +	return img.get_height();
    4.15 +}
    4.16 +
    4.17  void Texture::create2d(int xsz, int ysz)
    4.18  {
    4.19  	destroy();
     5.1 --- a/src/texture.h	Thu Aug 21 01:08:03 2014 +0300
     5.2 +++ b/src/texture.h	Fri Aug 22 16:55:16 2014 +0300
     5.3 @@ -13,6 +13,9 @@
     5.4  	Texture();
     5.5  	~Texture();
     5.6  
     5.7 +	int get_width() const;
     5.8 +	int get_height() const;
     5.9 +
    5.10  	void create2d(int xsz, int ysz);
    5.11  	void destroy();
    5.12  
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/vr/opt.c	Fri Aug 22 16:55:16 2014 +0300
     6.3 @@ -0,0 +1,81 @@
     6.4 +#include <stdio.h>
     6.5 +#include <stdlib.h>
     6.6 +#include <string.h>
     6.7 +#include <errno.h>
     6.8 +#include "opt.h"
     6.9 +#include "rbtree.h"
    6.10 +
    6.11 +static void opt_del_func(void *opt, void *cls)
    6.12 +{
    6.13 +	free(opt);
    6.14 +}
    6.15 +
    6.16 +void *create_options(void)
    6.17 +{
    6.18 +	struct rbtree *db = rb_create(RB_KEY_STRING);
    6.19 +	rb_set_delete_func(db, opt_del_func, 0);
    6.20 +	return db;
    6.21 +}
    6.22 +
    6.23 +void destroy_options(void *optdb)
    6.24 +{
    6.25 +	rb_destroy(optdb);
    6.26 +}
    6.27 +
    6.28 +void set_option_int(void *optdb, const char *key, int val)
    6.29 +{
    6.30 +	struct option *opt = malloc(sizeof *opt);
    6.31 +	if(!opt) {
    6.32 +		fprintf(stderr, "failed to set option: %s: %s\n", key, strerror(errno));
    6.33 +		return;
    6.34 +	}
    6.35 +	opt->type = OTYPE_INT;
    6.36 +	opt->ival = val;
    6.37 +	opt->fval = (float)val;
    6.38 +
    6.39 +	if(rb_insert(optdb, (void*)key, opt) == -1) {
    6.40 +		fprintf(stderr, "failed to set option: %s\n", key);
    6.41 +	}
    6.42 +	printf("stored %s -> %p\n", key, opt);
    6.43 +}
    6.44 +
    6.45 +void set_option_float(void *optdb, const char *key, float val)
    6.46 +{
    6.47 +	struct option *opt = malloc(sizeof *opt);
    6.48 +	if(!opt) {
    6.49 +		fprintf(stderr, "failed to set option: %s: %s\n", key, strerror(errno));
    6.50 +		return;
    6.51 +	}
    6.52 +	opt->type = OTYPE_FLOAT;
    6.53 +	opt->fval = val;
    6.54 +	opt->ival = (int)val;
    6.55 +
    6.56 +	if(rb_insert(optdb, (void*)key, opt) == -1) {
    6.57 +		fprintf(stderr, "failed to set option: %s\n", key);
    6.58 +	}
    6.59 +	printf("stored %s -> %p\n", key, opt);
    6.60 +}
    6.61 +
    6.62 +int get_option_int(void *optdb, const char *key, int *val)
    6.63 +{
    6.64 +	struct option *opt = rb_find(optdb, (void*)key);
    6.65 +	if(!opt) {
    6.66 +		*val = 0;
    6.67 +		return -1;
    6.68 +	}
    6.69 +	printf("got %s -> %p\n", key, opt);
    6.70 +	*val = opt->ival;
    6.71 +	return 0;
    6.72 +}
    6.73 +
    6.74 +int get_option_float(void *optdb, const char *key, float *val)
    6.75 +{
    6.76 +	struct option *opt = rb_find(optdb, (void*)key);
    6.77 +	if(!opt) {
    6.78 +		*val = 0.0f;
    6.79 +		return -1;
    6.80 +	}
    6.81 +	printf("got %s -> %p\n", key, opt);
    6.82 +	*val = opt->fval;
    6.83 +	return 0;
    6.84 +}
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/src/vr/opt.h	Fri Aug 22 16:55:16 2014 +0300
     7.3 @@ -0,0 +1,21 @@
     7.4 +#ifndef OPT_H_
     7.5 +#define OPT_H_
     7.6 +
     7.7 +enum opt_type { OTYPE_INT, OTYPE_FLOAT };
     7.8 +
     7.9 +struct option {
    7.10 +	enum opt_type type;
    7.11 +	int ival;
    7.12 +	float fval;
    7.13 +};
    7.14 +
    7.15 +void *create_options(void);
    7.16 +void destroy_options(void *optdb);
    7.17 +
    7.18 +void set_option_int(void *optdb, const char *key, int val);
    7.19 +void set_option_float(void *optdb, const char *key, float val);
    7.20 +
    7.21 +int get_option_int(void *optdb, const char *key, int *val);
    7.22 +int get_option_float(void *optdb, const char *key, float *val);
    7.23 +
    7.24 +#endif	/* OPT_H_ */
    7.25 \ No newline at end of file
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/src/vr/rbtree.c	Fri Aug 22 16:55:16 2014 +0300
     8.3 @@ -0,0 +1,501 @@
     8.4 +/*
     8.5 +rbtree - simple balanced binary search tree (red-black tree) library.
     8.6 +Copyright (C) 2011-2014  John Tsiombikas <nuclear@member.fsf.org>
     8.7 +
     8.8 +rbtree is free software, feel free to use, modify, and redistribute it, under
     8.9 +the terms of the 3-clause BSD license. See COPYING for details.
    8.10 + */
    8.11 +#include <stdio.h>
    8.12 +#include <stdlib.h>
    8.13 +#include <stdint.h>
    8.14 +#include <string.h>
    8.15 +#include "rbtree.h"
    8.16 +
    8.17 +#define INT2PTR(x)	((void*)(intptr_t)(x))
    8.18 +#define PTR2INT(x)	((int)(intptr_t)(x))
    8.19 +
    8.20 +struct rbtree {
    8.21 +	struct rbnode *root;
    8.22 +
    8.23 +	rb_alloc_func_t alloc;
    8.24 +	rb_free_func_t free;
    8.25 +
    8.26 +	rb_cmp_func_t cmp;
    8.27 +	rb_del_func_t del;
    8.28 +	void *del_cls;
    8.29 +
    8.30 +	struct rbnode *rstack, *iter;
    8.31 +};
    8.32 +
    8.33 +static int cmpaddr(const void *ap, const void *bp);
    8.34 +static int cmpint(const void *ap, const void *bp);
    8.35 +
    8.36 +static int count_nodes(struct rbnode *node);
    8.37 +static void del_tree(struct rbnode *node, void (*delfunc)(struct rbnode*, void*), void *cls);
    8.38 +static struct rbnode *insert(struct rbtree *rb, struct rbnode *tree, void *key, void *data);
    8.39 +static struct rbnode *delete(struct rbtree *rb, struct rbnode *tree, void *key);
    8.40 +/*static struct rbnode *find(struct rbtree *rb, struct rbnode *node, void *key);*/
    8.41 +static void traverse(struct rbnode *node, void (*func)(struct rbnode*, void*), void *cls);
    8.42 +
    8.43 +struct rbtree *rb_create(rb_cmp_func_t cmp_func)
    8.44 +{
    8.45 +	struct rbtree *rb;
    8.46 +
    8.47 +	if(!(rb = malloc(sizeof *rb))) {
    8.48 +		return 0;
    8.49 +	}
    8.50 +	if(rb_init(rb, cmp_func) == -1) {
    8.51 +		free(rb);
    8.52 +		return 0;
    8.53 +	}
    8.54 +	return rb;
    8.55 +}
    8.56 +
    8.57 +void rb_free(struct rbtree *rb)
    8.58 +{
    8.59 +	rb_destroy(rb);
    8.60 +	free(rb);
    8.61 +}
    8.62 +
    8.63 +
    8.64 +int rb_init(struct rbtree *rb, rb_cmp_func_t cmp_func)
    8.65 +{
    8.66 +	memset(rb, 0, sizeof *rb);
    8.67 +
    8.68 +	if(cmp_func == RB_KEY_INT) {
    8.69 +		rb->cmp = cmpint;
    8.70 +	} else if(cmp_func == RB_KEY_STRING) {
    8.71 +		rb->cmp = (rb_cmp_func_t)strcmp;
    8.72 +	} else {
    8.73 +		rb->cmp = cmpaddr;
    8.74 +	}
    8.75 +
    8.76 +	rb->alloc = malloc;
    8.77 +	rb->free = free;
    8.78 +	return 0;
    8.79 +}
    8.80 +
    8.81 +void rb_destroy(struct rbtree *rb)
    8.82 +{
    8.83 +	del_tree(rb->root, rb->del, rb->del_cls);
    8.84 +}
    8.85 +
    8.86 +void rb_set_allocator(struct rbtree *rb, rb_alloc_func_t alloc, rb_free_func_t free)
    8.87 +{
    8.88 +	rb->alloc = alloc;
    8.89 +	rb->free = free;
    8.90 +}
    8.91 +
    8.92 +
    8.93 +void rb_set_compare_func(struct rbtree *rb, rb_cmp_func_t func)
    8.94 +{
    8.95 +	rb->cmp = func;
    8.96 +}
    8.97 +
    8.98 +void rb_set_delete_func(struct rbtree *rb, rb_del_func_t func, void *cls)
    8.99 +{
   8.100 +	rb->del = func;
   8.101 +	rb->del_cls = cls;
   8.102 +}
   8.103 +
   8.104 +
   8.105 +void rb_clear(struct rbtree *rb)
   8.106 +{
   8.107 +	del_tree(rb->root, rb->del, rb->del_cls);
   8.108 +	rb->root = 0;
   8.109 +}
   8.110 +
   8.111 +int rb_copy(struct rbtree *dest, struct rbtree *src)
   8.112 +{
   8.113 +	struct rbnode *node;
   8.114 +
   8.115 +	rb_clear(dest);
   8.116 +	rb_begin(src);
   8.117 +	while((node = rb_next(src))) {
   8.118 +		if(rb_insert(dest, node->key, node->data) == -1) {
   8.119 +			return -1;
   8.120 +		}
   8.121 +	}
   8.122 +	return 0;
   8.123 +}
   8.124 +
   8.125 +int rb_size(struct rbtree *rb)
   8.126 +{
   8.127 +	return count_nodes(rb->root);
   8.128 +}
   8.129 +
   8.130 +int rb_insert(struct rbtree *rb, void *key, void *data)
   8.131 +{
   8.132 +	rb->root = insert(rb, rb->root, key, data);
   8.133 +	rb->root->red = 0;
   8.134 +	return 0;
   8.135 +}
   8.136 +
   8.137 +int rb_inserti(struct rbtree *rb, int key, void *data)
   8.138 +{
   8.139 +	rb->root = insert(rb, rb->root, INT2PTR(key), data);
   8.140 +	rb->root->red = 0;
   8.141 +	return 0;
   8.142 +}
   8.143 +
   8.144 +
   8.145 +int rb_delete(struct rbtree *rb, void *key)
   8.146 +{
   8.147 +	rb->root = delete(rb, rb->root, key);
   8.148 +	rb->root->red = 0;
   8.149 +	return 0;
   8.150 +}
   8.151 +
   8.152 +int rb_deletei(struct rbtree *rb, int key)
   8.153 +{
   8.154 +	rb->root = delete(rb, rb->root, INT2PTR(key));
   8.155 +	rb->root->red = 0;
   8.156 +	return 0;
   8.157 +}
   8.158 +
   8.159 +
   8.160 +void *rb_find(struct rbtree *rb, void *key)
   8.161 +{
   8.162 +	struct rbnode *node = rb->root;
   8.163 +
   8.164 +	while(node) {
   8.165 +		int cmp = rb->cmp(key, node->key);
   8.166 +		if(cmp == 0) {
   8.167 +			return node->data;
   8.168 +		}
   8.169 +		node = cmp < 0 ? node->left : node->right;
   8.170 +	}
   8.171 +	return 0;
   8.172 +}
   8.173 +
   8.174 +void *rb_findi(struct rbtree *rb, int key)
   8.175 +{
   8.176 +	return rb_find(rb, INT2PTR(key));
   8.177 +}
   8.178 +
   8.179 +
   8.180 +void rb_foreach(struct rbtree *rb, void (*func)(struct rbnode*, void*), void *cls)
   8.181 +{
   8.182 +	traverse(rb->root, func, cls);
   8.183 +}
   8.184 +
   8.185 +
   8.186 +struct rbnode *rb_root(struct rbtree *rb)
   8.187 +{
   8.188 +	return rb->root;
   8.189 +}
   8.190 +
   8.191 +void rb_begin(struct rbtree *rb)
   8.192 +{
   8.193 +	rb->rstack = 0;
   8.194 +	rb->iter = rb->root;
   8.195 +}
   8.196 +
   8.197 +#define push(sp, x)		((x)->next = (sp), (sp) = (x))
   8.198 +#define pop(sp)			((sp) = (sp)->next)
   8.199 +#define top(sp)			(sp)
   8.200 +
   8.201 +struct rbnode *rb_next(struct rbtree *rb)
   8.202 +{
   8.203 +	struct rbnode *res = 0;
   8.204 +
   8.205 +	while(rb->rstack || rb->iter) {
   8.206 +		if(rb->iter) {
   8.207 +			push(rb->rstack, rb->iter);
   8.208 +			rb->iter = rb->iter->left;
   8.209 +		} else {
   8.210 +			rb->iter = top(rb->rstack);
   8.211 +			pop(rb->rstack);
   8.212 +			res = rb->iter;
   8.213 +			rb->iter = rb->iter->right;
   8.214 +			break;
   8.215 +		}
   8.216 +	}
   8.217 +	return res;
   8.218 +}
   8.219 +
   8.220 +void *rb_node_key(struct rbnode *node)
   8.221 +{
   8.222 +	return node ? node->key : 0;
   8.223 +}
   8.224 +
   8.225 +int rb_node_keyi(struct rbnode *node)
   8.226 +{
   8.227 +	return node ? PTR2INT(node->key) : 0;
   8.228 +}
   8.229 +
   8.230 +void *rb_node_data(struct rbnode *node)
   8.231 +{
   8.232 +	return node ? node->data : 0;
   8.233 +}
   8.234 +
   8.235 +static int cmpaddr(const void *ap, const void *bp)
   8.236 +{
   8.237 +	return ap < bp ? -1 : (ap > bp ? 1 : 0);
   8.238 +}
   8.239 +
   8.240 +static int cmpint(const void *ap, const void *bp)
   8.241 +{
   8.242 +	return PTR2INT(ap) - PTR2INT(bp);
   8.243 +}
   8.244 +
   8.245 +
   8.246 +/* ---- left-leaning 2-3 red-black implementation ---- */
   8.247 +
   8.248 +/* helper prototypes */
   8.249 +static int is_red(struct rbnode *tree);
   8.250 +static void color_flip(struct rbnode *tree);
   8.251 +static struct rbnode *rot_left(struct rbnode *a);
   8.252 +static struct rbnode *rot_right(struct rbnode *a);
   8.253 +static struct rbnode *find_min(struct rbnode *tree);
   8.254 +static struct rbnode *del_min(struct rbtree *rb, struct rbnode *tree);
   8.255 +/*static struct rbnode *move_red_right(struct rbnode *tree);*/
   8.256 +static struct rbnode *move_red_left(struct rbnode *tree);
   8.257 +static struct rbnode *fix_up(struct rbnode *tree);
   8.258 +
   8.259 +static int count_nodes(struct rbnode *node)
   8.260 +{
   8.261 +	if(!node)
   8.262 +		return 0;
   8.263 +
   8.264 +	return 1 + count_nodes(node->left) + count_nodes(node->right);
   8.265 +}
   8.266 +
   8.267 +static void del_tree(struct rbnode *node, rb_del_func_t delfunc, void *cls)
   8.268 +{
   8.269 +	if(!node)
   8.270 +		return;
   8.271 +
   8.272 +	del_tree(node->left, delfunc, cls);
   8.273 +	del_tree(node->right, delfunc, cls);
   8.274 +
   8.275 +	if(delfunc) {
   8.276 +		delfunc(node, cls);
   8.277 +	}
   8.278 +	free(node);
   8.279 +}
   8.280 +
   8.281 +static struct rbnode *insert(struct rbtree *rb, struct rbnode *tree, void *key, void *data)
   8.282 +{
   8.283 +	int cmp;
   8.284 +
   8.285 +	if(!tree) {
   8.286 +		struct rbnode *node = rb->alloc(sizeof *node);
   8.287 +		node->red = 1;
   8.288 +		node->key = key;
   8.289 +		node->data = data;
   8.290 +		node->left = node->right = 0;
   8.291 +		return node;
   8.292 +	}
   8.293 +
   8.294 +	cmp = rb->cmp(key, tree->key);
   8.295 +
   8.296 +	if(cmp < 0) {
   8.297 +		tree->left = insert(rb, tree->left, key, data);
   8.298 +	} else if(cmp > 0) {
   8.299 +		tree->right = insert(rb, tree->right, key, data);
   8.300 +	} else {
   8.301 +		tree->data = data;
   8.302 +	}
   8.303 +
   8.304 +	/* fix right-leaning reds */
   8.305 +	if(is_red(tree->right)) {
   8.306 +		tree = rot_left(tree);
   8.307 +	}
   8.308 +	/* fix two reds in a row */
   8.309 +	if(is_red(tree->left) && is_red(tree->left->left)) {
   8.310 +		tree = rot_right(tree);
   8.311 +	}
   8.312 +
   8.313 +	/* if 4-node, split it by color inversion */
   8.314 +	if(is_red(tree->left) && is_red(tree->right)) {
   8.315 +		color_flip(tree);
   8.316 +	}
   8.317 +
   8.318 +	return tree;
   8.319 +}
   8.320 +
   8.321 +static struct rbnode *delete(struct rbtree *rb, struct rbnode *tree, void *key)
   8.322 +{
   8.323 +	int cmp;
   8.324 +
   8.325 +	if(!tree) {
   8.326 +		return 0;
   8.327 +	}
   8.328 +
   8.329 +	cmp = rb->cmp(key, tree->key);
   8.330 +
   8.331 +	if(cmp < 0) {
   8.332 +		if(!is_red(tree->left) && !is_red(tree->left->left)) {
   8.333 +			tree = move_red_left(tree);
   8.334 +		}
   8.335 +		tree->left = delete(rb, tree->left, key);
   8.336 +	} else {
   8.337 +		/* need reds on the right */
   8.338 +		if(is_red(tree->left)) {
   8.339 +			tree = rot_right(tree);
   8.340 +		}
   8.341 +
   8.342 +		/* found it at the bottom (XXX what certifies left is null?) */
   8.343 +		if(cmp == 0 && !tree->right) {
   8.344 +			if(rb->del) {
   8.345 +				rb->del(tree, rb->del_cls);
   8.346 +			}
   8.347 +			rb->free(tree);
   8.348 +			return 0;
   8.349 +		}
   8.350 +
   8.351 +		if(!is_red(tree->right) && !is_red(tree->right->left)) {
   8.352 +			tree = move_red_left(tree);
   8.353 +		}
   8.354 +
   8.355 +		if(key == tree->key) {
   8.356 +			struct rbnode *rmin = find_min(tree->right);
   8.357 +			tree->key = rmin->key;
   8.358 +			tree->data = rmin->data;
   8.359 +			tree->right = del_min(rb, tree->right);
   8.360 +		} else {
   8.361 +			tree->right = delete(rb, tree->right, key);
   8.362 +		}
   8.363 +	}
   8.364 +
   8.365 +	return fix_up(tree);
   8.366 +}
   8.367 +
   8.368 +/*static struct rbnode *find(struct rbtree *rb, struct rbnode *node, void *key)
   8.369 +{
   8.370 +	int cmp;
   8.371 +
   8.372 +	if(!node)
   8.373 +		return 0;
   8.374 +
   8.375 +	if((cmp = rb->cmp(key, node->key)) == 0) {
   8.376 +		return node;
   8.377 +	}
   8.378 +	return find(rb, cmp < 0 ? node->left : node->right, key);
   8.379 +}*/
   8.380 +
   8.381 +static void traverse(struct rbnode *node, void (*func)(struct rbnode*, void*), void *cls)
   8.382 +{
   8.383 +	if(!node)
   8.384 +		return;
   8.385 +
   8.386 +	traverse(node->left, func, cls);
   8.387 +	func(node, cls);
   8.388 +	traverse(node->right, func, cls);
   8.389 +}
   8.390 +
   8.391 +/* helpers */
   8.392 +
   8.393 +static int is_red(struct rbnode *tree)
   8.394 +{
   8.395 +	return tree && tree->red;
   8.396 +}
   8.397 +
   8.398 +static void color_flip(struct rbnode *tree)
   8.399 +{
   8.400 +	tree->red = !tree->red;
   8.401 +	tree->left->red = !tree->left->red;
   8.402 +	tree->right->red = !tree->right->red;
   8.403 +}
   8.404 +
   8.405 +static struct rbnode *rot_left(struct rbnode *a)
   8.406 +{
   8.407 +	struct rbnode *b = a->right;
   8.408 +	a->right = b->left;
   8.409 +	b->left = a;
   8.410 +	b->red = a->red;
   8.411 +	a->red = 1;
   8.412 +	return b;
   8.413 +}
   8.414 +
   8.415 +static struct rbnode *rot_right(struct rbnode *a)
   8.416 +{
   8.417 +	struct rbnode *b = a->left;
   8.418 +	a->left = b->right;
   8.419 +	b->right = a;
   8.420 +	b->red = a->red;
   8.421 +	a->red = 1;
   8.422 +	return b;
   8.423 +}
   8.424 +
   8.425 +static struct rbnode *find_min(struct rbnode *tree)
   8.426 +{
   8.427 +	struct rbnode *node = tree;
   8.428 +
   8.429 +	if(!tree)
   8.430 +		return 0;
   8.431 +
   8.432 +	while(node->left) {
   8.433 +		node = node->left;
   8.434 +	}
   8.435 +	return node;
   8.436 +}
   8.437 +
   8.438 +static struct rbnode *del_min(struct rbtree *rb, struct rbnode *tree)
   8.439 +{
   8.440 +	if(!tree->left) {
   8.441 +		if(rb->del) {
   8.442 +			rb->del(tree->left, rb->del_cls);
   8.443 +		}
   8.444 +		rb->free(tree->left);
   8.445 +		return 0;
   8.446 +	}
   8.447 +
   8.448 +	/* make sure we've got red (3/4-nodes) at the left side so we can delete at the bottom */
   8.449 +	if(!is_red(tree->left) && !is_red(tree->left->left)) {
   8.450 +		tree = move_red_left(tree);
   8.451 +	}
   8.452 +	tree->left = del_min(rb, tree->left);
   8.453 +
   8.454 +	/* fix right-reds, red-reds, and split 4-nodes on the way up */
   8.455 +	return fix_up(tree);
   8.456 +}
   8.457 +
   8.458 +#if 0
   8.459 +/* push a red link on this node to the right */
   8.460 +static struct rbnode *move_red_right(struct rbnode *tree)
   8.461 +{
   8.462 +	/* flipping it makes both children go red, so we have a red to the right */
   8.463 +	color_flip(tree);
   8.464 +
   8.465 +	/* if after the flip we've got a red-red situation to the left, fix it */
   8.466 +	if(is_red(tree->left->left)) {
   8.467 +		tree = rot_right(tree);
   8.468 +		color_flip(tree);
   8.469 +	}
   8.470 +	return tree;
   8.471 +}
   8.472 +#endif
   8.473 +
   8.474 +/* push a red link on this node to the left */
   8.475 +static struct rbnode *move_red_left(struct rbnode *tree)
   8.476 +{
   8.477 +	/* flipping it makes both children go red, so we have a red to the left */
   8.478 +	color_flip(tree);
   8.479 +
   8.480 +	/* if after the flip we've got a red-red on the right-left, fix it */
   8.481 +	if(is_red(tree->right->left)) {
   8.482 +		tree->right = rot_right(tree->right);
   8.483 +		tree = rot_left(tree);
   8.484 +		color_flip(tree);
   8.485 +	}
   8.486 +	return tree;
   8.487 +}
   8.488 +
   8.489 +static struct rbnode *fix_up(struct rbnode *tree)
   8.490 +{
   8.491 +	/* fix right-leaning */
   8.492 +	if(is_red(tree->right)) {
   8.493 +		tree = rot_left(tree);
   8.494 +	}
   8.495 +	/* change invalid red-red pairs into a proper 4-node */
   8.496 +	if(is_red(tree->left) && is_red(tree->left->left)) {
   8.497 +		tree = rot_right(tree);
   8.498 +	}
   8.499 +	/* split 4-nodes */
   8.500 +	if(is_red(tree->left) && is_red(tree->right)) {
   8.501 +		color_flip(tree);
   8.502 +	}
   8.503 +	return tree;
   8.504 +}
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/src/vr/rbtree.h	Fri Aug 22 16:55:16 2014 +0300
     9.3 @@ -0,0 +1,78 @@
     9.4 +/*
     9.5 +rbtree - simple balanced binary search tree (red-black tree) library.
     9.6 +Copyright (C) 2011-2014  John Tsiombikas <nuclear@member.fsf.org>
     9.7 +
     9.8 +rbtree is free software, feel free to use, modify, and redistribute it, under
     9.9 +the terms of the 3-clause BSD license. See COPYING for details.
    9.10 + */
    9.11 +#ifndef RBTREE_H_
    9.12 +#define RBTREE_H_
    9.13 +
    9.14 +struct rbtree;
    9.15 +
    9.16 +
    9.17 +struct rbnode {
    9.18 +	void *key, *data;
    9.19 +	int red;
    9.20 +	struct rbnode *left, *right;
    9.21 +	struct rbnode *next;	/* for iterator stack */
    9.22 +};
    9.23 +
    9.24 +
    9.25 +typedef void *(*rb_alloc_func_t)(size_t);
    9.26 +typedef void (*rb_free_func_t)(void*);
    9.27 +
    9.28 +typedef int (*rb_cmp_func_t)(const void*, const void*);
    9.29 +typedef void (*rb_del_func_t)(struct rbnode*, void*);
    9.30 +
    9.31 +#define RB_KEY_ADDR		(rb_cmp_func_t)(0)
    9.32 +#define RB_KEY_INT		(rb_cmp_func_t)(1)
    9.33 +#define RB_KEY_STRING	(rb_cmp_func_t)(3)
    9.34 +
    9.35 +
    9.36 +#ifdef __cplusplus
    9.37 +extern "C" {
    9.38 +#endif
    9.39 +
    9.40 +struct rbtree *rb_create(rb_cmp_func_t cmp_func);
    9.41 +void rb_free(struct rbtree *rb);
    9.42 +
    9.43 +int rb_init(struct rbtree *rb, rb_cmp_func_t cmp_func);
    9.44 +void rb_destroy(struct rbtree *rb);
    9.45 +
    9.46 +void rb_set_allocator(struct rbtree *rb, rb_alloc_func_t alloc, rb_free_func_t free);
    9.47 +void rb_set_compare_func(struct rbtree *rb, rb_cmp_func_t func);
    9.48 +void rb_set_delete_func(struct rbtree *rb, rb_del_func_t func, void *cls);
    9.49 +/* TODO add user deep copy function */
    9.50 +
    9.51 +void rb_clear(struct rbtree *rb);
    9.52 +int rb_copy(struct rbtree *dest, struct rbtree *src);
    9.53 +
    9.54 +int rb_size(struct rbtree *rb);
    9.55 +
    9.56 +int rb_insert(struct rbtree *rb, void *key, void *data);
    9.57 +int rb_inserti(struct rbtree *rb, int key, void *data);
    9.58 +
    9.59 +int rb_delete(struct rbtree *rb, void *key);
    9.60 +int rb_deletei(struct rbtree *rb, int key);
    9.61 +
    9.62 +void *rb_find(struct rbtree *rb, void *key);
    9.63 +void *rb_findi(struct rbtree *rb, int key);
    9.64 +
    9.65 +void rb_foreach(struct rbtree *rb, void (*func)(struct rbnode*, void*), void *cls);
    9.66 +
    9.67 +struct rbnode *rb_root(struct rbtree *rb);
    9.68 +
    9.69 +void rb_begin(struct rbtree *rb);
    9.70 +struct rbnode *rb_next(struct rbtree *rb);
    9.71 +
    9.72 +void *rb_node_key(struct rbnode *node);
    9.73 +int rb_node_keyi(struct rbnode *node);
    9.74 +void *rb_node_data(struct rbnode *node);
    9.75 +
    9.76 +#ifdef __cplusplus
    9.77 +}
    9.78 +#endif
    9.79 +
    9.80 +
    9.81 +#endif	/* RBTREE_H_ */
    10.1 --- a/src/vr/vr.c	Thu Aug 21 01:08:03 2014 +0300
    10.2 +++ b/src/vr/vr.c	Fri Aug 22 16:55:16 2014 +0300
    10.3 @@ -88,20 +88,72 @@
    10.4  	return -1;
    10.5  }
    10.6  
    10.7 +void vr_set_opti(const char *optname, int val)
    10.8 +{
    10.9 +	if(vrm && vrm->set_option) {
   10.10 +		vrm->set_option(optname, OTYPE_INT, &val);
   10.11 +	}
   10.12 +}
   10.13 +
   10.14 +void vr_set_optf(const char *optname, float val)
   10.15 +{
   10.16 +	if(vrm && vrm->set_option) {
   10.17 +		vrm->set_option(optname, OTYPE_FLOAT, &val);
   10.18 +	}
   10.19 +}
   10.20 +
   10.21 +int vr_get_opti(const char *optname)
   10.22 +{
   10.23 +	int res = 0;
   10.24 +
   10.25 +	if(vrm && vrm->get_option) {
   10.26 +		vrm->get_option(optname, OTYPE_INT, &res);
   10.27 +	}
   10.28 +	return res;
   10.29 +}
   10.30 +
   10.31 +float vr_get_optf(const char *optname)
   10.32 +{
   10.33 +	float res = 0.0f;
   10.34 +
   10.35 +	if(vrm && vrm->get_option) {
   10.36 +		vrm->get_option(optname, OTYPE_FLOAT, &res);
   10.37 +	}
   10.38 +	return res;
   10.39 +}
   10.40 +
   10.41 +
   10.42 +int vr_view_translation(int eye, float *vec)
   10.43 +{
   10.44 +	if(vrm && vrm->translation) {
   10.45 +		vrm->translation(eye, vec);
   10.46 +		return 0;
   10.47 +	}
   10.48 +	vec[0] = vec[1] = vec[2] = 0.0f;
   10.49 +	return -1;
   10.50 +}
   10.51 +
   10.52 +int vr_view_rotation(int eye, float *quat)
   10.53 +{
   10.54 +	if(vrm && vrm->rotation) {
   10.55 +		vrm->rotation(eye, quat);
   10.56 +		return 0;
   10.57 +	}
   10.58 +	quat[0] = quat[1] = quat[2] = 0.0f;
   10.59 +	quat[3] = 1.0f;
   10.60 +	return -1;
   10.61 +}
   10.62 +
   10.63  int vr_view_matrix(int eye, float *mat)
   10.64  {
   10.65 -	if(vrm && vrm->view_matrix) {
   10.66 -		vrm->view_matrix(eye, mat);
   10.67 -		return 1;
   10.68 -	}
   10.69 -	memcpy(mat, idmat, sizeof idmat);
   10.70 +	/* TODO combine vr_view_translation and vr_view_rotation */
   10.71  	return 0;
   10.72  }
   10.73  
   10.74 -int vr_proj_matrix(int eye, float *mat)
   10.75 +int vr_proj_matrix(int eye, float znear, float zfar, float *mat)
   10.76  {
   10.77  	if(vrm && vrm->proj_matrix) {
   10.78 -		vrm->proj_matrix(eye, mat);
   10.79 +		vrm->proj_matrix(eye, znear, zfar, mat);
   10.80  		return 1;
   10.81  	}
   10.82  	memcpy(mat, idmat, sizeof idmat);
   10.83 @@ -130,3 +182,25 @@
   10.84  	}
   10.85  	return 0;
   10.86  }
   10.87 +
   10.88 +void vr_output_texture(unsigned int tex, float umin, float vmin, float umax, float vmax)
   10.89 +{
   10.90 +	float halfu = (umax + umin) * 0.5f;
   10.91 +
   10.92 +	vr_output_texture_eye(VR_EYE_LEFT, tex, umin, vmin, halfu, vmax);
   10.93 +	vr_output_texture_eye(VR_EYE_RIGHT, tex, halfu, vmin, umax, vmax);
   10.94 +}
   10.95 +
   10.96 +void vr_output_texture_eye(int eye, unsigned int tex, float umin, float vmin, float umax, float vmax)
   10.97 +{
   10.98 +	if(vrm && vrm->set_eye_texture) {
   10.99 +		vrm->set_eye_texture(eye, tex, umin, vmin, umax, vmax);
  10.100 +	}
  10.101 +}
  10.102 +
  10.103 +void vr_recenter(void)
  10.104 +{
  10.105 +	if(vrm && vrm->recenter) {
  10.106 +		vrm->recenter();
  10.107 +	}
  10.108 +}
  10.109 \ No newline at end of file
    11.1 --- a/src/vr/vr.h	Thu Aug 21 01:08:03 2014 +0300
    11.2 +++ b/src/vr/vr.h	Fri Aug 22 16:55:16 2014 +0300
    11.3 @@ -1,6 +1,15 @@
    11.4  #ifndef VR_H_
    11.5  #define VR_H_
    11.6  
    11.7 +#define VR_OPT_DISPLAY_WIDTH	"display-xres"
    11.8 +#define VR_OPT_DISPLAY_HEIGHT	"display-yres"
    11.9 +#define VR_OPT_LEYE_XRES	"left-eye-xres"
   11.10 +#define VR_OPT_LEYE_YRES	"left-eye-yres"
   11.11 +#define VR_OPT_REYE_XRES	"right-eye-xres"
   11.12 +#define VR_OPT_REYE_YRES	"right-eye-yres"
   11.13 +#define VR_OPT_EYE_HEIGHT	"eye-height"
   11.14 +#define VR_OPT_IPD			"ipd"
   11.15 +
   11.16  enum {
   11.17  	VR_EYE_LEFT,
   11.18  	VR_EYE_RIGHT
   11.19 @@ -19,22 +28,30 @@
   11.20  int vr_use_module(int idx);
   11.21  int vr_use_module_named(const char *name);
   11.22  
   11.23 -/* if we're using a vr module which requires a specific output resolution, vr_display_size
   11.24 - * returns non-zero, and writes the size through the xsz/ysz pointers. Otherwise returns 0
   11.25 - */
   11.26 -int vr_display_size(int *xsz, int *ysz);
   11.27 -int vr_eye_texture_size(int eye, int *xsz, int *ysz);
   11.28 +void vr_set_opti(const char *optname, int val);
   11.29 +void vr_set_optf(const char *optname, float val);
   11.30 +int vr_get_opti(const char *optname);
   11.31 +float vr_get_optf(const char *optname);
   11.32 +
   11.33 +int vr_view_translation(int eye, float *vec);
   11.34 +int vr_view_rotation(int eye, float *quat);
   11.35  
   11.36  /* returns non-zero if the active vr module provides this kind of matrix
   11.37   * information, otherwise it returns zero, and sets mat to identity
   11.38   */
   11.39  int vr_view_matrix(int eye, float *mat);
   11.40 -int vr_proj_matrix(int eye, float *mat);
   11.41 +int vr_proj_matrix(int eye, float znear, float zfar, float *mat);
   11.42  
   11.43  void vr_begin(int eye);
   11.44  void vr_end(void);
   11.45  int vr_swap_buffers(void);
   11.46  
   11.47 +/* set the output texture or separate textures for each eye */
   11.48 +void vr_output_texture(unsigned int tex, float umin, float vmin, float umax, float vmax);
   11.49 +void vr_output_texture_eye(int eye, unsigned int tex, float umin, float vmin, float umax, float vmax);
   11.50 +
   11.51 +void vr_recenter(void);
   11.52 +
   11.53  #ifdef __cplusplus
   11.54  }
   11.55  #endif
    12.1 --- a/src/vr/vr_impl.h	Thu Aug 21 01:08:03 2014 +0300
    12.2 +++ b/src/vr/vr_impl.h	Fri Aug 22 16:55:16 2014 +0300
    12.3 @@ -1,18 +1,30 @@
    12.4  #ifndef VR_IMPL_H_
    12.5  #define VR_IMPL_H_
    12.6  
    12.7 +#include "vr.h"
    12.8 +#include "opt.h"
    12.9 +
   12.10  struct vr_module {
   12.11  	char *name;
   12.12  
   12.13  	int (*init)(void);
   12.14  	void (*cleanup)(void);
   12.15  
   12.16 -	void (*view_matrix)(int eye, float *mat);
   12.17 -	void (*proj_matrix)(int eye, float *mat);
   12.18 +	int (*set_option)(const char *opt, enum opt_type type, void *valp);
   12.19 +	int (*get_option)(const char *opt, enum opt_type type, void *valp);
   12.20 +
   12.21 +	void (*translation)(int eye, float *vec);
   12.22 +	void (*rotation)(int eye, float *quat);
   12.23 +
   12.24 +	void (*proj_matrix)(int eye, float znear, float zfar, float *mat);
   12.25  
   12.26  	void (*begin)(int eye);
   12.27  	void (*end)(void);
   12.28  	void (*present)(void);
   12.29 +
   12.30 +	void (*set_eye_texture)(int eye, unsigned int tex, float umin, float vmin, float umax, float vmax);
   12.31 +
   12.32 +	void (*recenter)(void);
   12.33  };
   12.34  
   12.35  void vr_init_modules(void);
    13.1 --- a/src/vr/vr_libovr.c	Thu Aug 21 01:08:03 2014 +0300
    13.2 +++ b/src/vr/vr_libovr.c	Fri Aug 22 16:55:16 2014 +0300
    13.3 @@ -2,20 +2,32 @@
    13.4  #define OVR_OS_WIN32
    13.5  #endif
    13.6  
    13.7 -#include <stdio.h>
    13.8 -#include <stdlib.h>
    13.9  #include "vr_impl.h"
   13.10  
   13.11  #ifdef USE_LIBOVR
   13.12 +#include <stdio.h>
   13.13 +#include <stdlib.h>
   13.14 +#include <assert.h>
   13.15 +#include "opt.h"
   13.16 +
   13.17  #include <OVR_CAPI.h>
   13.18  #include <OVR_CAPI_GL.h>
   13.19  
   13.20 +/* just dropping the prototype here to avoid including CAPI_HSWDisplay.h */
   13.21 +OVR_EXPORT void ovrhmd_EnableHSWDisplaySDKRender(ovrHmd hmd, ovrBool enabled);
   13.22 +
   13.23  static ovrHmd hmd;
   13.24 +static void *optdb;
   13.25 +static ovrEyeRenderDesc eye_render_desc[2];
   13.26 +static ovrSizei eye_res[2];
   13.27 +static ovrGLTexture eye_tex[2];
   13.28 +static ovrFovPort eye_fov[2];
   13.29 +static ovrPosef pose[2];
   13.30 +static int deferred_init_done;
   13.31  
   13.32  static int init(void)
   13.33  {
   13.34  	int i, num_hmds;
   13.35 -	union ovrGLConfig glcfg;
   13.36  
   13.37  	if(!ovr_Initialize()) {
   13.38  		return -1;
   13.39 @@ -48,48 +60,185 @@
   13.40  		return -1;
   13.41  	}
   13.42  
   13.43 +	eye_fov[0] = hmd->DefaultEyeFov[0];
   13.44 +	eye_fov[1] = hmd->DefaultEyeFov[1];
   13.45 +
   13.46 +	eye_res[0] = ovrHmd_GetFovTextureSize(hmd, ovrEye_Left, eye_fov[0], 1.0);
   13.47 +	eye_res[1] = ovrHmd_GetFovTextureSize(hmd, ovrEye_Right, eye_fov[1], 1.0);
   13.48 +
   13.49 +	/* create the options database */
   13.50 +	if((optdb = create_options())) {
   13.51 +		set_option_int(optdb, VR_OPT_DISPLAY_WIDTH, hmd->Resolution.w);
   13.52 +		set_option_int(optdb, VR_OPT_DISPLAY_HEIGHT, hmd->Resolution.h);
   13.53 +		set_option_int(optdb, VR_OPT_LEYE_XRES, eye_res[0].w);
   13.54 +		set_option_int(optdb, VR_OPT_LEYE_YRES, eye_res[0].h);
   13.55 +		set_option_int(optdb, VR_OPT_REYE_XRES, eye_res[1].w);
   13.56 +		set_option_int(optdb, VR_OPT_REYE_YRES, eye_res[1].h);
   13.57 +		set_option_float(optdb, VR_OPT_EYE_HEIGHT, ovrHmd_GetFloat(hmd, OVR_KEY_EYE_HEIGHT, OVR_DEFAULT_EYE_HEIGHT));
   13.58 +		set_option_float(optdb, VR_OPT_IPD, ovrHmd_GetFloat(hmd, OVR_KEY_IPD, OVR_DEFAULT_IPD));
   13.59 +	}
   13.60 +
   13.61 +	deferred_init_done = 0;
   13.62 +	return 0;
   13.63 +}
   13.64 +
   13.65 +static void deferred_init(void)
   13.66 +{
   13.67 +	union ovrGLConfig glcfg;
   13.68 +	unsigned int dcaps;
   13.69 +
   13.70 +	deferred_init_done = 1;
   13.71 +
   13.72  	ovrHmd_ConfigureTracking(hmd, 0xffffffff, 0);
   13.73  
   13.74  	glcfg.OGL.Header.API = ovrRenderAPI_OpenGL;
   13.75  	glcfg.OGL.Header.RTSize = hmd->Resolution;
   13.76  	glcfg.OGL.Header.Multisample = 0;
   13.77 -	glcfg.OGL.Window = 0;
   13.78 -	glcfg.OGL.DC = 0;
   13.79 +#ifdef WIN32
   13.80 +	glcfg.OGL.Window = GetActiveWindow();
   13.81 +	glcfg.OGL.DC = wglGetCurrentDC();
   13.82 +	ovrHmd_AttachToWindow(hmd, glcfg.OGL.Window, 0, 0);
   13.83 +	assert(glcfg.OGL.Window);
   13.84 +#endif
   13.85  
   13.86 -	if(!ovrHmd_ConfigureRendering(hmd, &glcfg.Config, distort_caps, eyes_fov, eye_rend_desc))) {
   13.87 +	dcaps = ovrDistortionCap_Chromatic | ovrDistortionCap_Vignette | ovrDistortionCap_TimeWarp |
   13.88 +		ovrDistortionCap_Overdrive | ovrDistortionCap_FlipInput;
   13.89 +
   13.90 +	if(!ovrHmd_ConfigureRendering(hmd, &glcfg.Config, dcaps, eye_fov, eye_render_desc)) {
   13.91  		fprintf(stderr, "failed to configure LibOVR distortion renderer\n");
   13.92 -		return -1;
   13.93  	}
   13.94 +
   13.95 +	ovrhmd_EnableHSWDisplaySDKRender(hmd, 0);
   13.96  }
   13.97  
   13.98  static void cleanup(void)
   13.99  {
  13.100  	if(hmd) {
  13.101  		ovrHmd_Destroy(hmd);
  13.102 -		ovr_Destroy();
  13.103 +		ovr_Shutdown();
  13.104  	}
  13.105  }
  13.106  
  13.107 -static void view_matrix(int eye, float *mat)
  13.108 +static int set_option(const char *opt, enum opt_type type, void *valp)
  13.109  {
  13.110 +	switch(type) {
  13.111 +	case OTYPE_INT:
  13.112 +		set_option_int(optdb, opt, *(int*)valp);
  13.113 +		break;
  13.114 +
  13.115 +	case OTYPE_FLOAT:
  13.116 +		set_option_float(optdb, opt, *(float*)valp);
  13.117 +		break;
  13.118 +	}
  13.119 +	return 0;
  13.120  }
  13.121  
  13.122 -static void proj_matrix(int eye, float *mat)
  13.123 +static int get_option(const char *opt, enum opt_type type, void *valp)
  13.124  {
  13.125 +	switch(type) {
  13.126 +	case OTYPE_INT:
  13.127 +		return get_option_int(optdb, opt, valp);
  13.128 +	case OTYPE_FLOAT:
  13.129 +		return get_option_float(optdb, opt, valp);
  13.130 +	}
  13.131 +	return -1;
  13.132  }
  13.133  
  13.134 +static int translation(int eye, float *vec)
  13.135 +{
  13.136 +	if(!hmd) {
  13.137 +		vec[0] = vec[1] = vec[2] = 0;
  13.138 +		return -1;
  13.139 +	}
  13.140 +
  13.141 +	pose[eye] = ovrHmd_GetEyePose(hmd, eye == VR_EYE_LEFT ? ovrEye_Left : ovrEye_Right);
  13.142 +	vec[0] = pose[eye].Position.x;
  13.143 +	vec[1] = pose[eye].Position.y;
  13.144 +	vec[2] = pose[eye].Position.z;
  13.145 +	return 0;
  13.146 +}
  13.147 +
  13.148 +static int rotation(int eye, float *quat)
  13.149 +{
  13.150 +	if(!hmd) {
  13.151 +		quat[0] = quat[1] = quat[2] = 0.0f;
  13.152 +		quat[3] = 1.0f;
  13.153 +		return -1;
  13.154 +	}
  13.155 +
  13.156 +	pose[eye] = ovrHmd_GetEyePose(hmd, eye == VR_EYE_LEFT ? ovrEye_Left : ovrEye_Right);
  13.157 +	quat[0] = pose[eye].Orientation.x;
  13.158 +	quat[1] = pose[eye].Orientation.y;
  13.159 +	quat[2] = pose[eye].Orientation.z;
  13.160 +	quat[3] = pose[eye].Orientation.w;
  13.161 +	return 0;
  13.162 +}
  13.163 +
  13.164 +static const float idmat[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
  13.165 +
  13.166 +static void proj_matrix(int eye, float znear, float zfar, float *mat)
  13.167 +{
  13.168 +	ovrMatrix4f vmat;
  13.169 +
  13.170 +	if(!hmd) {
  13.171 +		memcpy(mat, idmat, sizeof idmat);
  13.172 +		return;
  13.173 +	}
  13.174 +
  13.175 +	vmat = ovrMatrix4f_Projection(eye_render_desc[eye].Fov, znear, zfar, 1);
  13.176 +	memcpy(mat, vmat.M[0], 16 * sizeof(float));
  13.177 +}
  13.178 +
  13.179 +static int new_frame = 1;
  13.180 +
  13.181  static void begin(int eye)
  13.182  {
  13.183 -}
  13.184 +	if(!hmd) return;
  13.185  
  13.186 -static void end(void)
  13.187 -{
  13.188 +	if(!deferred_init_done) {
  13.189 +		deferred_init();
  13.190 +	}
  13.191 +
  13.192 +	if(new_frame) {
  13.193 +		ovrHmd_BeginFrame(hmd, 0);
  13.194 +		new_frame = 0;
  13.195 +	}
  13.196  }
  13.197  
  13.198  static void present(void)
  13.199  {
  13.200 +	if(!hmd) return;
  13.201 +
  13.202 +	ovrHmd_EndFrame(hmd, pose, &eye_tex[0].Texture);
  13.203 +	new_frame = 1;
  13.204  }
  13.205  
  13.206 +static void set_eye_texture(int eye, unsigned int tex, float umin, float vmin, float umax, float vmax)
  13.207 +{
  13.208 +	ovrSizei texsz;
  13.209 +	ovrRecti rect;
  13.210 +
  13.211 +	glBindTexture(GL_TEXTURE_2D, tex);
  13.212 +	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &texsz.w);
  13.213 +	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &texsz.h);
  13.214 +
  13.215 +	rect.Pos.x = (int)(umin * texsz.w);
  13.216 +	rect.Pos.y = (int)(vmin * texsz.h);
  13.217 +	rect.Size.w = (int)((umax - umin) * texsz.w);
  13.218 +	rect.Size.h = (int)((vmax - vmin) * texsz.h);
  13.219 +
  13.220 +	eye_tex[eye].OGL.Header.API = ovrRenderAPI_OpenGL;
  13.221 +	eye_tex[eye].OGL.Header.TextureSize = texsz;
  13.222 +	eye_tex[eye].OGL.Header.RenderViewport = rect;
  13.223 +	eye_tex[eye].OGL.TexId = tex;
  13.224 +}
  13.225 +
  13.226 +static void recenter(void)
  13.227 +{
  13.228 +	if(hmd) {
  13.229 +		ovrHmd_RecenterPose(hmd);
  13.230 +	}
  13.231 +}
  13.232  
  13.233  struct vr_module *vr_module_libovr(void)
  13.234  {
  13.235 @@ -99,11 +248,15 @@
  13.236  		m.name = "libovr";
  13.237  		m.init = init;
  13.238  		m.cleanup = cleanup;
  13.239 -		m.view_matrix = view_matrix;
  13.240 +		m.set_option = set_option;
  13.241 +		m.get_option = get_option;
  13.242 +		m.translation = translation;
  13.243 +		m.rotation = rotation;
  13.244  		m.proj_matrix = proj_matrix;
  13.245  		m.begin = begin;
  13.246 -		m.end = end;
  13.247  		m.present = present;
  13.248 +		m.set_eye_texture = set_eye_texture;
  13.249 +		m.recenter = recenter;
  13.250  	}
  13.251  	return &m;
  13.252  }
    14.1 --- a/src/vr/vr_null.c	Thu Aug 21 01:08:03 2014 +0300
    14.2 +++ b/src/vr/vr_null.c	Fri Aug 22 16:55:16 2014 +0300
    14.3 @@ -11,11 +11,71 @@
    14.4  
    14.5  #include "vr_impl.h"
    14.6  
    14.7 +static unsigned int eye_tex[2];
    14.8 +static float tex_umin[2], tex_umax[2];
    14.9 +static float tex_vmin[2], tex_vmax[2];
   14.10 +
   14.11  static int init(void)
   14.12  {
   14.13  	return 0;
   14.14  }
   14.15  
   14.16 +static void present(void)
   14.17 +{
   14.18 +	int i;
   14.19 +
   14.20 +	glPushAttrib(GL_ENABLE_BIT | GL_TRANSFORM_BIT);
   14.21 +
   14.22 +	glDisable(GL_LIGHTING);
   14.23 +	glDisable(GL_DEPTH_TEST);
   14.24 +	glDisable(GL_FOG);
   14.25 +	glDisable(GL_CULL_FACE);
   14.26 +
   14.27 +	glEnable(GL_TEXTURE_2D);
   14.28 +
   14.29 +	glMatrixMode(GL_MODELVIEW);
   14.30 +	glLoadIdentity();
   14.31 +	glMatrixMode(GL_PROJECTION);
   14.32 +	glLoadIdentity();
   14.33 +
   14.34 +	for(i=0; i<2; i++) {
   14.35 +		float x0 = i == 0 ? -1 : 0;
   14.36 +		float x1 = i == 0 ? 0 : 1;
   14.37 +
   14.38 +		glBindTexture(GL_TEXTURE_2D, eye_tex[i]);
   14.39 +
   14.40 +		glBegin(GL_QUADS);
   14.41 +		glTexCoord2f(tex_umin[i], tex_vmin[i]);
   14.42 +		glVertex2f(x0, -1);
   14.43 +		glTexCoord2f(tex_umax[i], tex_vmin[i]);
   14.44 +		glVertex2f(x1, -1);
   14.45 +		glTexCoord2f(tex_umax[i], tex_vmax[i]);
   14.46 +		glVertex2f(x1, 1);
   14.47 +		glTexCoord2f(tex_umin[i], tex_vmax[i]);
   14.48 +		glVertex2f(x0, 1);
   14.49 +		glEnd();
   14.50 +	}
   14.51 +
   14.52 +	glPopMatrix();
   14.53 +	glMatrixMode(GL_MODELVIEW);
   14.54 +	glPopMatrix();
   14.55 +
   14.56 +	glPopAttrib();
   14.57 +
   14.58 +#ifdef WIN32
   14.59 +	SwapBuffers(wglGetCurrentDC());
   14.60 +#endif
   14.61 +}
   14.62 +
   14.63 +static void set_eye_texture(int eye, unsigned int tex, float umin, float vmin, float umax, float vmax)
   14.64 +{
   14.65 +	eye_tex[eye] = tex;
   14.66 +	tex_umin[eye] = umin;
   14.67 +	tex_umax[eye] = umax;
   14.68 +	tex_vmin[eye] = vmin;
   14.69 +	tex_vmax[eye] = vmax;
   14.70 +}
   14.71 +
   14.72  struct vr_module *vr_module_null(void)
   14.73  {
   14.74  	static struct vr_module m;
   14.75 @@ -23,6 +83,8 @@
   14.76  	if(!m.init) {
   14.77  		m.name = "null";
   14.78  		m.init = init;
   14.79 +		m.set_eye_texture = set_eye_texture;
   14.80 +		m.present = present;
   14.81  	}
   14.82  	return &m;
   14.83  }
    15.1 --- a/vrchess.vcxproj	Thu Aug 21 01:08:03 2014 +0300
    15.2 +++ b/vrchess.vcxproj	Fri Aug 22 16:55:16 2014 +0300
    15.3 @@ -51,13 +51,14 @@
    15.4        </PrecompiledHeader>
    15.5        <WarningLevel>Level3</WarningLevel>
    15.6        <Optimization>Disabled</Optimization>
    15.7 -      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    15.8 +      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);USE_LIBOVR</PreprocessorDefinitions>
    15.9        <DisableSpecificWarnings>4996;4244;4305</DisableSpecificWarnings>
   15.10 +      <AdditionalIncludeDirectories>$(SolutionDir)\src</AdditionalIncludeDirectories>
   15.11      </ClCompile>
   15.12      <Link>
   15.13        <SubSystem>Console</SubSystem>
   15.14        <GenerateDebugInformation>true</GenerateDebugInformation>
   15.15 -      <AdditionalDependencies>opengl32.lib;glut32.lib;glew32.lib;libvmath.lib;libimago2.lib;jpeglib.lib;libpng.lib;zlib.lib;libovrd.lib;%(AdditionalDependencies)</AdditionalDependencies>
   15.16 +      <AdditionalDependencies>opengl32.lib;glut32.lib;glew32.lib;libvmath.lib;libimago2.lib;jpeglib.lib;libpng.lib;zlib.lib;libovrd.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
   15.17      </Link>
   15.18    </ItemDefinitionGroup>
   15.19    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
   15.20 @@ -68,15 +69,16 @@
   15.21        <Optimization>MaxSpeed</Optimization>
   15.22        <FunctionLevelLinking>true</FunctionLevelLinking>
   15.23        <IntrinsicFunctions>true</IntrinsicFunctions>
   15.24 -      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
   15.25 +      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);USE_LIBOVR</PreprocessorDefinitions>
   15.26        <DisableSpecificWarnings>4996;4244;4305</DisableSpecificWarnings>
   15.27 +      <AdditionalIncludeDirectories>$(SolutionDir)\src</AdditionalIncludeDirectories>
   15.28      </ClCompile>
   15.29      <Link>
   15.30        <SubSystem>Console</SubSystem>
   15.31        <GenerateDebugInformation>true</GenerateDebugInformation>
   15.32        <EnableCOMDATFolding>true</EnableCOMDATFolding>
   15.33        <OptimizeReferences>true</OptimizeReferences>
   15.34 -      <AdditionalDependencies>opengl32.lib;glut32.lib;glew32.lib;libvmath.lib;libimago2.lib;jpeglib.lib;libpng.lib;zlib.lib;libovr.lib;%(AdditionalDependencies)</AdditionalDependencies>
   15.35 +      <AdditionalDependencies>opengl32.lib;glut32.lib;glew32.lib;libvmath.lib;libimago2.lib;jpeglib.lib;libpng.lib;zlib.lib;libovr.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
   15.36      </Link>
   15.37    </ItemDefinitionGroup>
   15.38    <ItemGroup>
   15.39 @@ -87,6 +89,8 @@
   15.40      <ClCompile Include="src\opengl.cc" />
   15.41      <ClCompile Include="src\sdr.c" />
   15.42      <ClCompile Include="src\texture.cc" />
   15.43 +    <ClCompile Include="src\vr\opt.c" />
   15.44 +    <ClCompile Include="src\vr\rbtree.c" />
   15.45      <ClCompile Include="src\vr\vr.c" />
   15.46      <ClCompile Include="src\vr\vr_libovr.c" />
   15.47      <ClCompile Include="src\vr\vr_modules.c" />
   15.48 @@ -99,6 +103,8 @@
   15.49      <ClInclude Include="src\opengl.h" />
   15.50      <ClInclude Include="src\sdr.h" />
   15.51      <ClInclude Include="src\texture.h" />
   15.52 +    <ClInclude Include="src\vr\opt.h" />
   15.53 +    <ClInclude Include="src\vr\rbtree.h" />
   15.54      <ClInclude Include="src\vr\vr.h" />
   15.55      <ClInclude Include="src\vr\vr_impl.h" />
   15.56    </ItemGroup>
    16.1 --- a/vrchess.vcxproj.filters	Thu Aug 21 01:08:03 2014 +0300
    16.2 +++ b/vrchess.vcxproj.filters	Fri Aug 22 16:55:16 2014 +0300
    16.3 @@ -43,6 +43,12 @@
    16.4      <ClCompile Include="src\vr\vr_null.c">
    16.5        <Filter>src\vr</Filter>
    16.6      </ClCompile>
    16.7 +    <ClCompile Include="src\vr\rbtree.c">
    16.8 +      <Filter>src\vr</Filter>
    16.9 +    </ClCompile>
   16.10 +    <ClCompile Include="src\vr\opt.c">
   16.11 +      <Filter>src\vr</Filter>
   16.12 +    </ClCompile>
   16.13    </ItemGroup>
   16.14    <ItemGroup>
   16.15      <ClInclude Include="src\camera.h">
   16.16 @@ -69,5 +75,11 @@
   16.17      <ClInclude Include="src\vr\vr_impl.h">
   16.18        <Filter>src\vr</Filter>
   16.19      </ClInclude>
   16.20 +    <ClInclude Include="src\vr\rbtree.h">
   16.21 +      <Filter>src\vr</Filter>
   16.22 +    </ClInclude>
   16.23 +    <ClInclude Include="src\vr\opt.h">
   16.24 +      <Filter>src\vr</Filter>
   16.25 +    </ClInclude>
   16.26    </ItemGroup>
   16.27  </Project>
   16.28 \ No newline at end of file