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