oculus1
changeset 13:464e1d135d68
hurraaaay!
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 21 Sep 2013 03:00:47 +0300 |
parents | d797639e0234 |
children | cceffea995a4 |
files | sdr.glsl src/main.cc src/vr.cc src/vr_impl.h |
diffstat | 4 files changed, 170 insertions(+), 24 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/sdr.glsl Sat Sep 21 03:00:47 2013 +0300 1.3 @@ -0,0 +1,44 @@ 1.4 +uniform sampler2D tex; 1.5 +uniform float aspect, scale; 1.6 +uniform float lens_center_offset; 1.7 +uniform vec4 dist_factors; 1.8 + 1.9 +vec2 distort_texcoords(in vec2 tc, out float dbgrad); 1.10 +float barrel_scale(float x, in vec4 k); 1.11 + 1.12 +void main() 1.13 +{ 1.14 + float dbgrad; 1.15 + vec2 tc = distort_texcoords(gl_TexCoord[0].xy, dbgrad); 1.16 + 1.17 + gl_FragColor.rgb = texture2D(tex, tc).rgb; 1.18 + gl_FragColor.rgb += mix(vec3(1.0, 1.0, 0.0), vec3(0.0), smoothstep(0.01, 0.05, dbgrad)); 1.19 + gl_FragColor.a = 1.0; 1.20 +} 1.21 + 1.22 +vec2 distort_texcoords(in vec2 tc, out float dbgrad) 1.23 +{ 1.24 + // map tc [0, 1] -> [-1, 1] 1.25 + vec2 pt = tc * 2.0 - 1.0; 1.26 + 1.27 + pt.x += lens_center_offset * 2.0; 1.28 + pt.y /= aspect; // correct for aspect ratio 1.29 + 1.30 + float rad = barrel_scale(dot(pt, pt), dist_factors); 1.31 + pt *= rad; // scale the point by the computer distortion radius 1.32 + 1.33 + dbgrad = length(pt) * rad; 1.34 + 1.35 + pt.y *= aspect; 1.36 + pt.x -= lens_center_offset * 2.0; 1.37 + 1.38 + // map back to range [0, 1] 1.39 + return pt * 0.5 + 0.5; 1.40 +} 1.41 + 1.42 +float barrel_scale(float rad, in vec4 k) 1.43 +{ 1.44 + float radsq = rad * rad; 1.45 + float radquad = radsq * radsq; 1.46 + return k.x + k.y * radsq + k.z * radquad + k.w * radquad * radsq; 1.47 +}
2.1 --- a/src/main.cc Fri Sep 20 10:14:29 2013 +0300 2.2 +++ b/src/main.cc Sat Sep 21 03:00:47 2013 +0300 2.3 @@ -11,6 +11,7 @@ 2.4 static void disp(); 2.5 static void draw_scene(); 2.6 static void draw_teapot(); 2.7 +static void draw_squares(); 2.8 static void draw_grid(float size, float spacing); 2.9 static void idle(); 2.10 static void reshape(int x, int y); 2.11 @@ -32,7 +33,6 @@ 2.12 static int rtarg_width, rtarg_height; 2.13 static unsigned int fbo, tex[2], zbuf; 2.14 2.15 - 2.16 int main(int argc, char **argv) 2.17 { 2.18 glutInitWindowSize(1280, 800); 2.19 @@ -98,6 +98,8 @@ 2.20 rtarg_height = height; 2.21 } 2.22 2.23 + printf("render target: %dx%d\n", rtarg_width, rtarg_height); 2.24 + 2.25 // create render targets for each eye 2.26 GLenum wrap_mode = GL_CLAMP_TO_EDGE; 2.27 if(!GLEW_SGIS_texture_edge_clamp) { 2.28 @@ -142,9 +144,13 @@ 2.29 2.30 cam.track_vr(); 2.31 2.32 - glMatrixMode(GL_PROJECTION); 2.33 + /*glMatrixMode(GL_PROJECTION); 2.34 glLoadIdentity(); 2.35 - gluPerspective(RAD_TO_DEG(vr_get_fov()), (float)rtarg_width / (float)rtarg_height, 0.5, 500.0); 2.36 + float fov = RAD_TO_DEG(vr_get_fov()); 2.37 + gluPerspective(fov, (float)rtarg_width / (float)rtarg_height, 0.25, 500.0);*/ 2.38 + float proj_matrix[16]; 2.39 + 2.40 + float eye_dist = vr_get_eyedist(); 2.41 2.42 glViewport(0, 0, rtarg_width, rtarg_height); 2.43 2.44 @@ -156,10 +162,14 @@ 2.45 2.46 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 2.47 2.48 + glMatrixMode(GL_PROJECTION); 2.49 + vr_get_proj_matrix(proj_matrix, VR_EYE_LEFT); 2.50 + glLoadTransposeMatrixf(proj_matrix); 2.51 + 2.52 glMatrixMode(GL_MODELVIEW); 2.53 glLoadIdentity(); 2.54 + glTranslatef(eye_dist / 2.0, 0, 0); 2.55 cam.use_inverse(); 2.56 - glTranslatef(0.32, 0, 0); 2.57 draw_scene(); 2.58 2.59 2.60 @@ -169,10 +179,14 @@ 2.61 2.62 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 2.63 2.64 + glMatrixMode(GL_PROJECTION); 2.65 + vr_get_proj_matrix(proj_matrix, VR_EYE_RIGHT); 2.66 + glLoadTransposeMatrixf(proj_matrix); 2.67 + 2.68 glMatrixMode(GL_MODELVIEW); 2.69 glLoadIdentity(); 2.70 + glTranslatef(-eye_dist / 2.0, 0, 0); 2.71 cam.use_inverse(); 2.72 - glTranslatef(-0.32, 0, 0); 2.73 draw_scene(); 2.74 2.75 // return to the regular window framebuffer 2.76 @@ -187,6 +201,8 @@ 2.77 2.78 glutSwapBuffers(); 2.79 assert(glGetError() == GL_NO_ERROR); 2.80 + 2.81 + glFinish(); 2.82 } 2.83 2.84 2.85 @@ -195,6 +211,8 @@ 2.86 float lpos[] = {0, 60, 0, 1}; 2.87 glLightfv(GL_LIGHT0, GL_POSITION, lpos); 2.88 2.89 + draw_grid(100.0, 2.5); 2.90 + 2.91 static Vector2 teapos[] = { 2.92 Vector2(-8, 8), Vector2(8, 8), Vector2(8, -8), Vector2(-8, -8) 2.93 }; 2.94 @@ -206,7 +224,7 @@ 2.95 glPopMatrix(); 2.96 } 2.97 2.98 - draw_grid(100.0, 2.5); 2.99 + draw_squares(); 2.100 } 2.101 2.102 static void draw_teapot() 2.103 @@ -225,6 +243,37 @@ 2.104 glFrontFace(GL_CCW); 2.105 } 2.106 2.107 +static void draw_squares() 2.108 +{ 2.109 + static const int num_sq = 4; 2.110 + 2.111 + glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT); 2.112 + glDisable(GL_LIGHTING); 2.113 + 2.114 + glMatrixMode(GL_MODELVIEW); 2.115 + glPushMatrix(); 2.116 + glTranslatef(0, 1, 0); 2.117 + 2.118 + 2.119 + glLineWidth(3.0); 2.120 + glColor3f(1.0, 0.7, 0.2); 2.121 + 2.122 + float zdist = 2.0; 2.123 + for(int i=0; i<num_sq; i++) { 2.124 + glBegin(GL_LINE_LOOP); 2.125 + glVertex3f(-1, -1, -zdist); 2.126 + glVertex3f(1, -1, -zdist); 2.127 + glVertex3f(1, 1, -zdist); 2.128 + glVertex3f(-1, 1, -zdist); 2.129 + glEnd(); 2.130 + 2.131 + zdist += 1.0; 2.132 + } 2.133 + 2.134 + glPopMatrix(); 2.135 + glPopAttrib(); 2.136 +} 2.137 + 2.138 static void draw_grid(float size, float spacing) 2.139 { 2.140 int num_lines = size / spacing;
3.1 --- a/src/vr.cc Fri Sep 20 10:14:29 2013 +0300 3.2 +++ b/src/vr.cc Sat Sep 21 03:00:47 2013 +0300 3.3 @@ -11,20 +11,24 @@ 3.4 "uniform vec2 scale_in;\n" 3.5 "uniform vec4 warp_param;\n" 3.6 "\n" 3.7 - "vec2 warp(in vec2 pt)\n" 3.8 + "vec2 warp(in vec2 pt, out float dbgrad)\n" 3.9 "{\n" 3.10 " vec2 theta = (pt - lens_center) * scale_in;\n" 3.11 - " float rsq = length(theta);\n" 3.12 - " vec2 rvec = theta * (warp_param.x + warp_param.y * rsq +\n" 3.13 + " float rsq = dot(theta, theta);\n" 3.14 + " vec2 rvec = theta * (warp_param.x + \n" 3.15 + " warp_param.y * rsq +\n" 3.16 " warp_param.z * rsq * rsq +\n" 3.17 " warp_param.w * rsq * rsq * rsq);\n" 3.18 + " dbgrad = length(theta);\n" 3.19 " return lens_center + scale * rvec;\n" 3.20 "}\n" 3.21 "\n" 3.22 "void main()\n" 3.23 "{\n" 3.24 - " vec2 tc = warp(gl_TexCoord[0].xy);\n" 3.25 + " float dbgrad;\n" 3.26 + " vec2 tc = warp(gl_TexCoord[0].xy, dbgrad);\n" 3.27 " gl_FragColor.rgb = texture2D(tex, tc).rgb;\n" 3.28 + " gl_FragColor.rgb += mix(vec3(1.0, 1.0, 0.0), vec3(0.0), smoothstep(0.01, 0.05, dbgrad));\n" 3.29 " gl_FragColor.a = 1.0;\n" 3.30 "}\n"; 3.31 3.32 @@ -94,9 +98,6 @@ 3.33 } 3.34 3.35 // calculate and store viewing parameters 3.36 - float vhalfsz = info.VScreenSize * 0.5; 3.37 - vr_ctx.info.fov = 2.0 * atan(vhalfsz / info.EyeToScreenDistance); 3.38 - 3.39 vr_ctx.info.width = info.HResolution; 3.40 vr_ctx.info.height = info.VResolution; 3.41 vr_ctx.info.aspect = (float)vr_ctx.info.width / (float)vr_ctx.info.height; 3.42 @@ -106,7 +107,17 @@ 3.43 vr_ctx.info.distort[i] = info.DistortionK[i]; 3.44 } 3.45 3.46 - vr_ctx.info.lens_center = info.LensSeparationDistance / info.HScreenSize; 3.47 + vr_ctx.info.scale = 1.0; 3.48 + 3.49 + float vhalfsz = vr_ctx.info.scale * info.VScreenSize * 0.5; 3.50 + vr_ctx.info.fov = 2.0 * atan(vhalfsz / info.EyeToScreenDistance); 3.51 + 3.52 + vr_ctx.info.lens_center_offset = 0.5 - info.LensSeparationDistance / info.HScreenSize; 3.53 + 3.54 + // calculate center of projection shift to match the lens positions 3.55 + float center_dist_meters = info.HScreenSize * 0.25; 3.56 + float proj_shift = center_dist_meters - info.LensSeparationDistance * 0.5; 3.57 + vr_ctx.info.proj_center_offset = 4.0 * proj_shift / info.HScreenSize; 3.58 } 3.59 3.60 // get the sensor device 3.61 @@ -132,10 +143,30 @@ 3.62 return true; 3.63 } 3.64 3.65 +#define EXTERNAL_SHADER 3.66 + 3.67 static bool init_sdr() 3.68 { 3.69 int status; 3.70 3.71 +#ifdef EXTERNAL_SHADER 3.72 + FILE *fp = fopen("sdr.glsl", "rb"); 3.73 + if(!fp) { 3.74 + perror("failed to load sdr.glsl"); 3.75 + return false; 3.76 + } 3.77 + fseek(fp, 0, SEEK_END); 3.78 + long sz = ftell(fp); 3.79 + rewind(fp); 3.80 + 3.81 + char *buf = (char*)alloca(sz + 1); 3.82 + fread(buf, 1, sz, fp); 3.83 + buf[sz] = 0; 3.84 + sdr_src = buf; 3.85 + 3.86 + fclose(fp); 3.87 +#endif 3.88 + 3.89 unsigned int sdr = glCreateShader(GL_FRAGMENT_SHADER); 3.90 glShaderSource(sdr, 1, &sdr_src, 0); 3.91 glCompileShader(sdr); 3.92 @@ -161,19 +192,23 @@ 3.93 if((loc = glGetUniformLocation(sdrprog, "tex")) != -1) { 3.94 glUniform1i(loc, 0); 3.95 } 3.96 - if((loc = glGetUniformLocation(sdrprog, "lens_center")) != -1) { 3.97 - glUniform2f(loc, 0.5, 0.5); 3.98 + if((loc = glGetUniformLocation(sdrprog, "lens_center_offset")) != -1) { 3.99 + glUniform1f(loc, 0); 3.100 } 3.101 if((loc = glGetUniformLocation(sdrprog, "scr_center")) != -1) { 3.102 glUniform2f(loc, 0, 0); 3.103 } 3.104 if((loc = glGetUniformLocation(sdrprog, "scale")) != -1) { 3.105 - glUniform2f(loc, 1, 1); 3.106 + glUniform1f(loc, vr_ctx.info.scale); 3.107 + } 3.108 + if((loc = glGetUniformLocation(sdrprog, "aspect")) != -1) { 3.109 + printf("setting aspect: %f\n", vr_ctx.info.aspect / 2.0); 3.110 + glUniform1f(loc, vr_ctx.info.aspect / 2.0); 3.111 } 3.112 if((loc = glGetUniformLocation(sdrprog, "scale_in")) != -1) { 3.113 glUniform2f(loc, 1, 1); 3.114 } 3.115 - if((loc = glGetUniformLocation(sdrprog, "warp_param")) != -1) { 3.116 + if((loc = glGetUniformLocation(sdrprog, "dist_factors")) != -1) { 3.117 glUniform4f(loc, vr_ctx.info.distort[0], vr_ctx.info.distort[1], 3.118 vr_ctx.info.distort[2], vr_ctx.info.distort[3]); 3.119 } 3.120 @@ -231,6 +266,21 @@ 3.121 return vr_ctx.ovr_sfusion.GetPredictionDelta(); 3.122 } 3.123 3.124 +extern "C" void vr_get_view_matrix(float *res, int eye) 3.125 +{ 3.126 + // TODO 3.127 +} 3.128 + 3.129 +extern "C" void vr_get_proj_matrix(float *res, int eye) 3.130 +{ 3.131 + static float eye_scale[] = {0.0, 1.0, -1.0}; 3.132 + 3.133 + Matrix4f proj = Matrix4f::PerspectiveRH(vr_ctx.info.fov, vr_ctx.info.aspect / 2.0, 0.3, 1000.0); 3.134 + proj = Matrix4f::Translation(vr_ctx.info.proj_center_offset * eye_scale[eye], 0, 0) * proj; 3.135 + 3.136 + memcpy(res, proj.M[0], 16 * sizeof(float)); 3.137 +} 3.138 + 3.139 extern "C" void vr_get_translation(float *offs) 3.140 { 3.141 // current oculus devkit doesn't do translation 3.142 @@ -276,11 +326,12 @@ 3.143 3.144 glUseProgram(sdrprog); 3.145 3.146 - int loc; 3.147 - if((loc = glGetUniformLocation(sdrprog, "lens_center")) != -1) { 3.148 - float lens_center = 0.5 - vr_ctx.info.lens_center * offs_scale[eye]; 3.149 - glUniform2f(loc, lens_center, 0.5); 3.150 - printf("lens_center = %f\n", lens_center); 3.151 + if(sdrprog) { 3.152 + int loc; 3.153 + if((loc = glGetUniformLocation(sdrprog, "lens_center_offset")) != -1) { 3.154 + float offset = vr_ctx.info.lens_center_offset * offs_scale[eye]; 3.155 + glUniform1f(loc, offset); 3.156 + } 3.157 } 3.158 3.159 glBindTexture(GL_TEXTURE_2D, tex);
4.1 --- a/src/vr_impl.h Fri Sep 20 10:14:29 2013 +0300 4.2 +++ b/src/vr_impl.h Sat Sep 21 03:00:47 2013 +0300 4.3 @@ -20,7 +20,9 @@ 4.4 float ipd; 4.5 float distort[4]; 4.6 // the right lens center offset (negate for left) 4.7 - float lens_center; 4.8 + float lens_center_offset; 4.9 + float proj_center_offset; 4.10 + float scale; // scaling to be applied to the two views to fill the screen 4.11 } info; 4.12 }; 4.13