oculus1

diff src/vr.cc @ 13:464e1d135d68

hurraaaay!
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 21 Sep 2013 03:00:47 +0300
parents d797639e0234
children cceffea995a4
line diff
     1.1 --- a/src/vr.cc	Fri Sep 20 10:14:29 2013 +0300
     1.2 +++ b/src/vr.cc	Sat Sep 21 03:00:47 2013 +0300
     1.3 @@ -11,20 +11,24 @@
     1.4  	"uniform vec2 scale_in;\n"
     1.5  	"uniform vec4 warp_param;\n"
     1.6  	"\n"
     1.7 -	"vec2 warp(in vec2 pt)\n"
     1.8 +	"vec2 warp(in vec2 pt, out float dbgrad)\n"
     1.9  	"{\n"
    1.10  	"    vec2 theta = (pt - lens_center) * scale_in;\n"
    1.11 -	"    float rsq = length(theta);\n"
    1.12 -	"    vec2 rvec = theta * (warp_param.x + warp_param.y * rsq +\n"
    1.13 +	"    float rsq = dot(theta, theta);\n"
    1.14 +	"    vec2 rvec = theta * (warp_param.x + \n"
    1.15 +	"                         warp_param.y * rsq +\n"
    1.16  	"                         warp_param.z * rsq * rsq +\n"
    1.17  	"                         warp_param.w * rsq * rsq * rsq);\n"
    1.18 +	"    dbgrad = length(theta);\n"
    1.19  	"    return lens_center + scale * rvec;\n"
    1.20  	"}\n"
    1.21  	"\n"
    1.22  	"void main()\n"
    1.23  	"{\n"
    1.24 -	"    vec2 tc = warp(gl_TexCoord[0].xy);\n"
    1.25 +	"    float dbgrad;\n"
    1.26 +	"    vec2 tc = warp(gl_TexCoord[0].xy, dbgrad);\n"
    1.27  	"    gl_FragColor.rgb = texture2D(tex, tc).rgb;\n"
    1.28 +	"    gl_FragColor.rgb += mix(vec3(1.0, 1.0, 0.0), vec3(0.0), smoothstep(0.01, 0.05, dbgrad));\n"
    1.29  	"    gl_FragColor.a = 1.0;\n"
    1.30  	"}\n";
    1.31  
    1.32 @@ -94,9 +98,6 @@
    1.33  		}
    1.34  
    1.35  		// calculate and store viewing parameters
    1.36 -		float vhalfsz = info.VScreenSize * 0.5;
    1.37 -		vr_ctx.info.fov = 2.0 * atan(vhalfsz / info.EyeToScreenDistance);
    1.38 -
    1.39  		vr_ctx.info.width = info.HResolution;
    1.40  		vr_ctx.info.height = info.VResolution;
    1.41  		vr_ctx.info.aspect = (float)vr_ctx.info.width / (float)vr_ctx.info.height;
    1.42 @@ -106,7 +107,17 @@
    1.43  			vr_ctx.info.distort[i] = info.DistortionK[i];
    1.44  		}
    1.45  
    1.46 -		vr_ctx.info.lens_center = info.LensSeparationDistance / info.HScreenSize;
    1.47 +		vr_ctx.info.scale = 1.0;
    1.48 +
    1.49 +		float vhalfsz = vr_ctx.info.scale * info.VScreenSize * 0.5;
    1.50 +		vr_ctx.info.fov = 2.0 * atan(vhalfsz / info.EyeToScreenDistance);
    1.51 +
    1.52 +		vr_ctx.info.lens_center_offset = 0.5 - info.LensSeparationDistance / info.HScreenSize;
    1.53 +
    1.54 +		// calculate center of projection shift to match the lens positions
    1.55 +		float center_dist_meters = info.HScreenSize * 0.25;
    1.56 +		float proj_shift = center_dist_meters - info.LensSeparationDistance * 0.5;
    1.57 +		vr_ctx.info.proj_center_offset = 4.0 * proj_shift / info.HScreenSize;
    1.58  	}
    1.59  
    1.60  	// get the sensor device
    1.61 @@ -132,10 +143,30 @@
    1.62  	return true;
    1.63  }
    1.64  
    1.65 +#define EXTERNAL_SHADER
    1.66 +
    1.67  static bool init_sdr()
    1.68  {
    1.69  	int status;
    1.70  
    1.71 +#ifdef EXTERNAL_SHADER
    1.72 +	FILE *fp = fopen("sdr.glsl", "rb");
    1.73 +	if(!fp) {
    1.74 +		perror("failed to load sdr.glsl");
    1.75 +		return false;
    1.76 +	}
    1.77 +	fseek(fp, 0, SEEK_END);
    1.78 +	long sz = ftell(fp);
    1.79 +	rewind(fp);
    1.80 +
    1.81 +	char *buf = (char*)alloca(sz + 1);
    1.82 +	fread(buf, 1, sz, fp);
    1.83 +	buf[sz] = 0;
    1.84 +	sdr_src = buf;
    1.85 +
    1.86 +	fclose(fp);
    1.87 +#endif
    1.88 +
    1.89  	unsigned int sdr = glCreateShader(GL_FRAGMENT_SHADER);
    1.90  	glShaderSource(sdr, 1, &sdr_src, 0);
    1.91  	glCompileShader(sdr);
    1.92 @@ -161,19 +192,23 @@
    1.93  	if((loc = glGetUniformLocation(sdrprog, "tex")) != -1) {
    1.94  		glUniform1i(loc, 0);
    1.95  	}
    1.96 -	if((loc = glGetUniformLocation(sdrprog, "lens_center")) != -1) {
    1.97 -		glUniform2f(loc, 0.5, 0.5);
    1.98 +	if((loc = glGetUniformLocation(sdrprog, "lens_center_offset")) != -1) {
    1.99 +		glUniform1f(loc, 0);
   1.100  	}
   1.101  	if((loc = glGetUniformLocation(sdrprog, "scr_center")) != -1) {
   1.102  		glUniform2f(loc, 0, 0);
   1.103  	}
   1.104  	if((loc = glGetUniformLocation(sdrprog, "scale")) != -1) {
   1.105 -		glUniform2f(loc, 1, 1);
   1.106 +		glUniform1f(loc, vr_ctx.info.scale);
   1.107 +	}
   1.108 +	if((loc = glGetUniformLocation(sdrprog, "aspect")) != -1) {
   1.109 +		printf("setting aspect: %f\n", vr_ctx.info.aspect / 2.0);
   1.110 +		glUniform1f(loc, vr_ctx.info.aspect / 2.0);
   1.111  	}
   1.112  	if((loc = glGetUniformLocation(sdrprog, "scale_in")) != -1) {
   1.113  		glUniform2f(loc, 1, 1);
   1.114  	}
   1.115 -	if((loc = glGetUniformLocation(sdrprog, "warp_param")) != -1) {
   1.116 +	if((loc = glGetUniformLocation(sdrprog, "dist_factors")) != -1) {
   1.117  		glUniform4f(loc, vr_ctx.info.distort[0], vr_ctx.info.distort[1],
   1.118  				vr_ctx.info.distort[2], vr_ctx.info.distort[3]);
   1.119  	}
   1.120 @@ -231,6 +266,21 @@
   1.121  	return vr_ctx.ovr_sfusion.GetPredictionDelta();
   1.122  }
   1.123  
   1.124 +extern "C" void vr_get_view_matrix(float *res, int eye)
   1.125 +{
   1.126 +	// TODO
   1.127 +}
   1.128 +
   1.129 +extern "C" void vr_get_proj_matrix(float *res, int eye)
   1.130 +{
   1.131 +	static float eye_scale[] = {0.0, 1.0, -1.0};
   1.132 +
   1.133 +	Matrix4f proj = Matrix4f::PerspectiveRH(vr_ctx.info.fov, vr_ctx.info.aspect / 2.0, 0.3, 1000.0);
   1.134 +	proj = Matrix4f::Translation(vr_ctx.info.proj_center_offset * eye_scale[eye], 0, 0) * proj;
   1.135 +
   1.136 +	memcpy(res, proj.M[0], 16 * sizeof(float));
   1.137 +}
   1.138 +
   1.139  extern "C" void vr_get_translation(float *offs)
   1.140  {
   1.141  	// current oculus devkit doesn't do translation
   1.142 @@ -276,11 +326,12 @@
   1.143  
   1.144  	glUseProgram(sdrprog);
   1.145  
   1.146 -	int loc;
   1.147 -	if((loc = glGetUniformLocation(sdrprog, "lens_center")) != -1) {
   1.148 -		float lens_center = 0.5 - vr_ctx.info.lens_center * offs_scale[eye];
   1.149 -		glUniform2f(loc, lens_center, 0.5);
   1.150 -		printf("lens_center = %f\n", lens_center);
   1.151 +	if(sdrprog) {
   1.152 +		int loc;
   1.153 +		if((loc = glGetUniformLocation(sdrprog, "lens_center_offset")) != -1) {
   1.154 +			float offset = vr_ctx.info.lens_center_offset * offs_scale[eye];
   1.155 +			glUniform1f(loc, offset);
   1.156 +		}
   1.157  	}
   1.158  
   1.159  	glBindTexture(GL_TEXTURE_2D, tex);