vrchess
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