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_