oculus1
changeset 12:d797639e0234
moving on to the distortion... not correct yet
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Fri, 20 Sep 2013 10:14:29 +0300 |
parents | 39ec672a5158 |
children | 464e1d135d68 |
files | src/main.cc src/vr.cc src/vr.h src/vr_impl.h |
diffstat | 4 files changed, 278 insertions(+), 33 deletions(-) [+] |
line diff
1.1 --- a/src/main.cc Fri Sep 20 07:00:18 2013 +0300 1.2 +++ b/src/main.cc Fri Sep 20 10:14:29 2013 +0300 1.3 @@ -10,6 +10,8 @@ 1.4 static void cleanup(); 1.5 static void disp(); 1.6 static void draw_scene(); 1.7 +static void draw_teapot(); 1.8 +static void draw_grid(float size, float spacing); 1.9 static void idle(); 1.10 static void reshape(int x, int y); 1.11 static void keyb(unsigned char key, int x, int y); 1.12 @@ -27,6 +29,9 @@ 1.13 1.14 static bool keystate[256]; 1.15 1.16 +static int rtarg_width, rtarg_height; 1.17 +static unsigned int fbo, tex[2], zbuf; 1.18 + 1.19 1.20 int main(int argc, char **argv) 1.21 { 1.22 @@ -37,8 +42,11 @@ 1.23 return 1; 1.24 } 1.25 1.26 - glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE | GLUT_MULTISAMPLE); 1.27 - glutCreateWindow("oculus test 01"); 1.28 + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); 1.29 + glutCreateWindow("oculus vr test 01"); 1.30 + 1.31 + width = glutGet(GLUT_WINDOW_WIDTH); 1.32 + height = glutGet(GLUT_WINDOW_HEIGHT); 1.33 1.34 glutDisplayFunc(disp); 1.35 glutIdleFunc(idle); 1.36 @@ -62,10 +70,6 @@ 1.37 { 1.38 glewInit(); // this must be first 1.39 1.40 - if(GLEW_ARB_multisample) { 1.41 - glEnable(GL_MULTISAMPLE); 1.42 - } 1.43 - 1.44 glEnable(GL_DEPTH_TEST); 1.45 glEnable(GL_LIGHTING); 1.46 glEnable(GL_CULL_FACE); 1.47 @@ -76,14 +80,59 @@ 1.48 // y = height of neck 1.49 cam.input_move(0, 1.65, 0); 1.50 1.51 - if(vr_init(VR_INIT_OCULUS) == -1) { 1.52 - return false; 1.53 + if(use_vr) { 1.54 + if(vr_init(VR_INIT_OCULUS) == -1) { 1.55 + return false; 1.56 + } 1.57 + 1.58 + // reshape to the size of the VR display 1.59 + int xsz = vr_get_width(); 1.60 + int ysz = vr_get_height(); 1.61 + 1.62 + glutReshapeWindow(xsz, ysz); 1.63 + 1.64 + rtarg_width = (xsz + xsz / 2) / 2; 1.65 + rtarg_height = ysz + ysz / 2; 1.66 + } else { 1.67 + rtarg_width = width; 1.68 + rtarg_height = height; 1.69 } 1.70 + 1.71 + // create render targets for each eye 1.72 + GLenum wrap_mode = GL_CLAMP_TO_EDGE; 1.73 + if(!GLEW_SGIS_texture_edge_clamp) { 1.74 + wrap_mode = GL_CLAMP; 1.75 + } 1.76 + 1.77 + glGenTextures(2, tex); 1.78 + for(int i=0; i<2; i++) { 1.79 + glBindTexture(GL_TEXTURE_2D, tex[i]); 1.80 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1.81 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 1.82 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_mode); 1.83 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_mode); 1.84 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, rtarg_width, rtarg_height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 1.85 + } 1.86 + 1.87 + // create the depth render buffer 1.88 + glGenRenderbuffers(1, &zbuf); 1.89 + glBindRenderbuffer(GL_RENDERBUFFER, zbuf); 1.90 + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, rtarg_width, rtarg_height); 1.91 + 1.92 + // create the FBO 1.93 + glGenFramebuffers(1, &fbo); 1.94 + glBindFramebuffer(GL_FRAMEBUFFER, fbo); 1.95 + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex[0], 0); 1.96 + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, zbuf); 1.97 + 1.98 return true; 1.99 } 1.100 1.101 static void cleanup() 1.102 { 1.103 + glDeleteTextures(2, tex); 1.104 + glDeleteRenderbuffers(1, &zbuf); 1.105 + glDeleteFramebuffers(1, &fbo); 1.106 vr_shutdown(); 1.107 } 1.108 1.109 @@ -91,24 +140,75 @@ 1.110 { 1.111 unsigned int msec = glutGet(GLUT_ELAPSED_TIME); 1.112 1.113 - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 1.114 + cam.track_vr(); 1.115 1.116 glMatrixMode(GL_PROJECTION); 1.117 glLoadIdentity(); 1.118 - gluPerspective(45.0, (float)width / (float)height, 0.5, 500.0); 1.119 + gluPerspective(RAD_TO_DEG(vr_get_fov()), (float)rtarg_width / (float)rtarg_height, 0.5, 500.0); 1.120 + 1.121 + glViewport(0, 0, rtarg_width, rtarg_height); 1.122 + 1.123 + glClearColor(0.1, 0.1, 0.1, 1.0); 1.124 + 1.125 + // draw left view 1.126 + glBindFramebuffer(GL_FRAMEBUFFER, fbo); 1.127 + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex[0], 0); 1.128 + 1.129 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 1.130 1.131 glMatrixMode(GL_MODELVIEW); 1.132 glLoadIdentity(); 1.133 + cam.use_inverse(); 1.134 + glTranslatef(0.32, 0, 0); 1.135 + draw_scene(); 1.136 1.137 - cam.track_vr(); 1.138 + 1.139 + // draw right view 1.140 + glBindFramebuffer(GL_FRAMEBUFFER, fbo); 1.141 + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex[1], 0); 1.142 + 1.143 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 1.144 + 1.145 + glMatrixMode(GL_MODELVIEW); 1.146 + glLoadIdentity(); 1.147 cam.use_inverse(); 1.148 + glTranslatef(-0.32, 0, 0); 1.149 + draw_scene(); 1.150 1.151 - draw_scene(); 1.152 + // return to the regular window framebuffer 1.153 + glBindFramebuffer(GL_FRAMEBUFFER, 0); 1.154 + glViewport(0, 0, width, height); 1.155 + 1.156 + glClearColor(0, 0, 0, 0); 1.157 + glClear(GL_COLOR_BUFFER_BIT); 1.158 + 1.159 + vr_draw_eye(tex[0], VR_EYE_LEFT); 1.160 + vr_draw_eye(tex[1], VR_EYE_RIGHT); 1.161 1.162 glutSwapBuffers(); 1.163 assert(glGetError() == GL_NO_ERROR); 1.164 } 1.165 1.166 + 1.167 +static void draw_scene() 1.168 +{ 1.169 + float lpos[] = {0, 60, 0, 1}; 1.170 + glLightfv(GL_LIGHT0, GL_POSITION, lpos); 1.171 + 1.172 + static Vector2 teapos[] = { 1.173 + Vector2(-8, 8), Vector2(8, 8), Vector2(8, -8), Vector2(-8, -8) 1.174 + }; 1.175 + 1.176 + for(int i=0; i<4; i++) { 1.177 + glPushMatrix(); 1.178 + glTranslatef(teapos[i].x, 0, teapos[i].y); 1.179 + draw_teapot(); 1.180 + glPopMatrix(); 1.181 + } 1.182 + 1.183 + draw_grid(100.0, 2.5); 1.184 +} 1.185 + 1.186 static void draw_teapot() 1.187 { 1.188 static int tealist; 1.189 @@ -125,7 +225,7 @@ 1.190 glFrontFace(GL_CCW); 1.191 } 1.192 1.193 -void draw_grid(float size, float spacing) 1.194 +static void draw_grid(float size, float spacing) 1.195 { 1.196 int num_lines = size / spacing; 1.197 float dist = size / 2.0; 1.198 @@ -164,26 +264,6 @@ 1.199 glPopAttrib(); 1.200 } 1.201 1.202 - 1.203 -static void draw_scene() 1.204 -{ 1.205 - float lpos[] = {0, 60, 0, 1}; 1.206 - glLightfv(GL_LIGHT0, GL_POSITION, lpos); 1.207 - 1.208 - static Vector2 teapos[] = { 1.209 - Vector2(-8, 8), Vector2(8, 8), Vector2(8, -8), Vector2(-8, -8) 1.210 - }; 1.211 - 1.212 - for(int i=0; i<4; i++) { 1.213 - glPushMatrix(); 1.214 - glTranslatef(teapos[i].x, 0, teapos[i].y); 1.215 - draw_teapot(); 1.216 - glPopMatrix(); 1.217 - } 1.218 - 1.219 - draw_grid(100.0, 2.5); 1.220 -} 1.221 - 1.222 static void idle() 1.223 { 1.224 glutPostRedisplay(); 1.225 @@ -194,6 +274,11 @@ 1.226 { 1.227 width = x; 1.228 height = y; 1.229 + 1.230 + if(!use_vr) { 1.231 + rtarg_width = width; 1.232 + rtarg_height = height; 1.233 + } 1.234 } 1.235 1.236 static void keyb(unsigned char key, int x, int y) 1.237 @@ -213,6 +298,24 @@ 1.238 glutSetCursor(GLUT_CURSOR_INHERIT); 1.239 } 1.240 break; 1.241 + 1.242 + case 'f': 1.243 + { 1.244 + static bool fullscreen; 1.245 + static int prev_xsz, prev_ysz; 1.246 + 1.247 + fullscreen = !fullscreen; 1.248 + 1.249 + if(fullscreen) { 1.250 + prev_xsz = width; 1.251 + prev_ysz = height; 1.252 + glutFullScreen(); 1.253 + } else { 1.254 + glutReshapeWindow(prev_xsz, prev_ysz); 1.255 + } 1.256 + glutPostRedisplay(); 1.257 + } 1.258 + break; 1.259 } 1.260 1.261 keystate[key] = true;
2.1 --- a/src/vr.cc Fri Sep 20 07:00:18 2013 +0300 2.2 +++ b/src/vr.cc Fri Sep 20 10:14:29 2013 +0300 2.3 @@ -1,16 +1,51 @@ 2.4 #include <stdio.h> 2.5 +#include <GL/glew.h> 2.6 #include "vr.h" 2.7 #include "vr_impl.h" 2.8 2.9 +static const char *sdr_src = 2.10 + "uniform sampler2D tex;\n" 2.11 + "uniform vec2 lens_center;\n" 2.12 + "uniform vec2 scr_center;\n" 2.13 + "uniform vec2 scale;\n" 2.14 + "uniform vec2 scale_in;\n" 2.15 + "uniform vec4 warp_param;\n" 2.16 + "\n" 2.17 + "vec2 warp(in vec2 pt)\n" 2.18 + "{\n" 2.19 + " vec2 theta = (pt - lens_center) * scale_in;\n" 2.20 + " float rsq = length(theta);\n" 2.21 + " vec2 rvec = theta * (warp_param.x + warp_param.y * rsq +\n" 2.22 + " warp_param.z * rsq * rsq +\n" 2.23 + " warp_param.w * rsq * rsq * rsq);\n" 2.24 + " return lens_center + scale * rvec;\n" 2.25 + "}\n" 2.26 + "\n" 2.27 + "void main()\n" 2.28 + "{\n" 2.29 + " vec2 tc = warp(gl_TexCoord[0].xy);\n" 2.30 + " gl_FragColor.rgb = texture2D(tex, tc).rgb;\n" 2.31 + " gl_FragColor.a = 1.0;\n" 2.32 + "}\n"; 2.33 + 2.34 static bool init_ovr(); 2.35 +static bool init_sdr(); 2.36 2.37 VRContext vr_ctx; 2.38 +static unsigned int sdrprog; 2.39 2.40 extern "C" int vr_init(enum vr_init_mode mode) 2.41 { 2.42 + glewInit(); 2.43 + 2.44 if(!init_ovr()) { 2.45 return -1; 2.46 } 2.47 + 2.48 + if(!init_sdr()) { 2.49 + return -1; 2.50 + } 2.51 + 2.52 return 0; 2.53 } 2.54 2.55 @@ -70,6 +105,8 @@ 2.56 for(int i=0; i<4; i++) { 2.57 vr_ctx.info.distort[i] = info.DistortionK[i]; 2.58 } 2.59 + 2.60 + vr_ctx.info.lens_center = info.LensSeparationDistance / info.HScreenSize; 2.61 } 2.62 2.63 // get the sensor device 2.64 @@ -95,6 +132,55 @@ 2.65 return true; 2.66 } 2.67 2.68 +static bool init_sdr() 2.69 +{ 2.70 + int status; 2.71 + 2.72 + unsigned int sdr = glCreateShader(GL_FRAGMENT_SHADER); 2.73 + glShaderSource(sdr, 1, &sdr_src, 0); 2.74 + glCompileShader(sdr); 2.75 + glGetShaderiv(sdr, GL_COMPILE_STATUS, &status); 2.76 + if(!status) { 2.77 + fprintf(stderr, "failed to compile distortion shader\n"); 2.78 + return false; 2.79 + } 2.80 + 2.81 + sdrprog = glCreateProgram(); 2.82 + glAttachShader(sdrprog, sdr); 2.83 + glLinkProgram(sdrprog); 2.84 + if(!status) { 2.85 + fprintf(stderr, "failed to link distortion shader program\n"); 2.86 + glDeleteShader(sdr); 2.87 + return false; 2.88 + } 2.89 + 2.90 + int loc; 2.91 + 2.92 + glUseProgram(sdrprog); 2.93 + 2.94 + if((loc = glGetUniformLocation(sdrprog, "tex")) != -1) { 2.95 + glUniform1i(loc, 0); 2.96 + } 2.97 + if((loc = glGetUniformLocation(sdrprog, "lens_center")) != -1) { 2.98 + glUniform2f(loc, 0.5, 0.5); 2.99 + } 2.100 + if((loc = glGetUniformLocation(sdrprog, "scr_center")) != -1) { 2.101 + glUniform2f(loc, 0, 0); 2.102 + } 2.103 + if((loc = glGetUniformLocation(sdrprog, "scale")) != -1) { 2.104 + glUniform2f(loc, 1, 1); 2.105 + } 2.106 + if((loc = glGetUniformLocation(sdrprog, "scale_in")) != -1) { 2.107 + glUniform2f(loc, 1, 1); 2.108 + } 2.109 + if((loc = glGetUniformLocation(sdrprog, "warp_param")) != -1) { 2.110 + glUniform4f(loc, vr_ctx.info.distort[0], vr_ctx.info.distort[1], 2.111 + vr_ctx.info.distort[2], vr_ctx.info.distort[3]); 2.112 + } 2.113 + 2.114 + return true; 2.115 +} 2.116 + 2.117 extern "C" int vr_get_width(void) 2.118 { 2.119 return vr_ctx.info.width; 2.120 @@ -165,3 +251,52 @@ 2.121 Quatf oq = vr_ctx.ovr_sfusion.GetPredictedOrientation(); 2.122 oq.GetEulerAngles<Axis_Y, Axis_X, Axis_Z>(euler + 1, euler, euler + 2); 2.123 } 2.124 + 2.125 +extern "C" void vr_draw_eye(unsigned int tex, int eye) 2.126 +{ 2.127 + static const float rects[3][4] = { 2.128 + {-1, -1, 1, 1}, 2.129 + {-1, -1, 0, 1}, 2.130 + {0, -1, 1, 1} 2.131 + }; 2.132 + static const float offs_scale[3] = {0.0, -1.0, 1.0}; 2.133 + 2.134 + glPushAttrib(GL_ENABLE_BIT); 2.135 + glDisable(GL_DEPTH_TEST); 2.136 + glDisable(GL_LIGHTING); 2.137 + glEnable(GL_TEXTURE_2D); 2.138 + 2.139 + glMatrixMode(GL_MODELVIEW); 2.140 + glPushMatrix(); 2.141 + glLoadIdentity(); 2.142 + 2.143 + glMatrixMode(GL_PROJECTION); 2.144 + glPushMatrix(); 2.145 + glLoadIdentity(); 2.146 + 2.147 + glUseProgram(sdrprog); 2.148 + 2.149 + int loc; 2.150 + if((loc = glGetUniformLocation(sdrprog, "lens_center")) != -1) { 2.151 + float lens_center = 0.5 - vr_ctx.info.lens_center * offs_scale[eye]; 2.152 + glUniform2f(loc, lens_center, 0.5); 2.153 + printf("lens_center = %f\n", lens_center); 2.154 + } 2.155 + 2.156 + glBindTexture(GL_TEXTURE_2D, tex); 2.157 + glBegin(GL_QUADS); 2.158 + glColor4f(1, 1, 1, 1); 2.159 + glTexCoord2f(0, 0); glVertex2f(rects[eye][0], rects[eye][1]); 2.160 + glTexCoord2f(1, 0); glVertex2f(rects[eye][2], rects[eye][1]); 2.161 + glTexCoord2f(1, 1); glVertex2f(rects[eye][2], rects[eye][3]); 2.162 + glTexCoord2f(0, 1); glVertex2f(rects[eye][0], rects[eye][3]); 2.163 + glEnd(); 2.164 + 2.165 + glUseProgram(0); 2.166 + 2.167 + glPopMatrix(); 2.168 + glMatrixMode(GL_MODELVIEW); 2.169 + glPopMatrix(); 2.170 + 2.171 + glPopAttrib(); 2.172 +}
3.1 --- a/src/vr.h Fri Sep 20 07:00:18 2013 +0300 3.2 +++ b/src/vr.h Fri Sep 20 10:14:29 2013 +0300 3.3 @@ -22,6 +22,9 @@ 3.4 int vr_init(enum vr_init_mode mode); 3.5 void vr_shutdown(void); 3.6 3.7 +int vr_get_width(void); 3.8 +int vr_get_height(void); 3.9 + 3.10 float vr_get_fov(void); 3.11 float vr_get_aspect(void); 3.12
4.1 --- a/src/vr_impl.h Fri Sep 20 07:00:18 2013 +0300 4.2 +++ b/src/vr_impl.h Fri Sep 20 10:14:29 2013 +0300 4.3 @@ -19,9 +19,13 @@ 4.4 float aspect; 4.5 float ipd; 4.6 float distort[4]; 4.7 + // the right lens center offset (negate for left) 4.8 + float lens_center; 4.9 } info; 4.10 }; 4.11 4.12 extern VRContext vr_ctx; 4.13 4.14 +bool vr_gl_init(); 4.15 + 4.16 #endif // VR_IMPL_H_