oculus1
changeset 21:ef4c9d8eeca7
added shaderless distortion method
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Wed, 02 Oct 2013 04:09:37 +0300 |
parents | ff3bfd4da86b |
children | 9dc19419f52b 9f783284a503 |
files | oculus1.vcproj src/main.cc src/vr.cc |
diffstat | 3 files changed, 228 insertions(+), 23 deletions(-) [+] |
line diff
1.1 --- a/oculus1.vcproj Tue Oct 01 12:51:20 2013 +0300 1.2 +++ b/oculus1.vcproj Wed Oct 02 04:09:37 2013 +0300 1.3 @@ -553,6 +553,22 @@ 1.4 </File> 1.5 </Filter> 1.6 </Filter> 1.7 + <Filter 1.8 + Name="sdr" 1.9 + > 1.10 + <File 1.11 + RelativePath=".\sdr\phong.p.glsl" 1.12 + > 1.13 + </File> 1.14 + <File 1.15 + RelativePath=".\sdr\phong.v.glsl" 1.16 + > 1.17 + </File> 1.18 + <File 1.19 + RelativePath=".\sdr\sdr.glsl" 1.20 + > 1.21 + </File> 1.22 + </Filter> 1.23 </Files> 1.24 <Globals> 1.25 </Globals>
2.1 --- a/src/main.cc Tue Oct 01 12:51:20 2013 +0300 2.2 +++ b/src/main.cc Wed Oct 02 04:09:37 2013 +0300 2.3 @@ -515,6 +515,13 @@ 2.4 case 'f': 2.5 toggle_fullscreen(); 2.6 break; 2.7 + 2.8 + case '\\': 2.9 + { 2.10 + extern bool dbg_enable; 2.11 + dbg_enable = !dbg_enable; 2.12 + } 2.13 + break; 2.14 } 2.15 2.16 keystate[key] = true;
3.1 --- a/src/vr.cc Tue Oct 01 12:51:20 2013 +0300 3.2 +++ b/src/vr.cc Wed Oct 02 04:09:37 2013 +0300 3.3 @@ -10,13 +10,40 @@ 3.4 #include <malloc.h> 3.5 #endif 3.6 3.7 +#define USUB 28 3.8 +#define VSUB 40 3.9 + 3.10 +/* these are just used for the shaderless precomputed distortion method */ 3.11 +struct Mesh { 3.12 + int prim; 3.13 + int num_verts, num_faces; 3.14 + unsigned int vbo; 3.15 + unsigned int ibo; 3.16 +}; 3.17 +struct Vertex { 3.18 + float x, y, z; 3.19 + float tx, ty; 3.20 +}; 3.21 + 3.22 + 3.23 static void init_ctx(); 3.24 static bool init_ovr(); 3.25 static bool init_sdr(); 3.26 3.27 +static Mesh gen_view_mesh(int usub, int vsub, float aspect, float lens_center_offset, 3.28 + float scale, const float *dist_factors, float tex_scale_x, float tex_scale_y); 3.29 +static void distort_texcoords(float *tc, float aspect, float lens_center_offset, float scale, const float *dist_factors); 3.30 +static float barrel_scale(float rad, const float *k); 3.31 + 3.32 VRContext vr_ctx; 3.33 static unsigned int sdrprog; 3.34 3.35 +static Mesh wrapmesh[2]; 3.36 +static bool mesh_valid; 3.37 + 3.38 +bool dbg_enable; 3.39 + 3.40 + 3.41 extern "C" int vr_init(enum vr_init_mode mode) 3.42 { 3.43 glewInit(); 3.44 @@ -338,49 +365,204 @@ 3.45 {-1, -1, 0, 1}, 3.46 {0, -1, 1, 1} 3.47 }; 3.48 + static const float quad_trans[3] = {0, -1, 1}; 3.49 + static const float quad_scale[3] = {1, 0.5, 0.5}; 3.50 static const float offs_scale[3] = {0.0, -1.0, 1.0}; 3.51 + static int prev_tex_scale_x, prev_tex_scale_y; 3.52 3.53 glPushAttrib(GL_ENABLE_BIT); 3.54 glDisable(GL_DEPTH_TEST); 3.55 glDisable(GL_LIGHTING); 3.56 - glEnable(GL_TEXTURE_2D); 3.57 + glDisable(GL_CULL_FACE); 3.58 + 3.59 + glMatrixMode(GL_PROJECTION); 3.60 + glPushMatrix(); 3.61 + glLoadIdentity(); 3.62 3.63 glMatrixMode(GL_MODELVIEW); 3.64 glPushMatrix(); 3.65 glLoadIdentity(); 3.66 3.67 - glMatrixMode(GL_PROJECTION); 3.68 - glPushMatrix(); 3.69 - glLoadIdentity(); 3.70 + if(!dbg_enable) { 3.71 + glUseProgram(sdrprog); 3.72 3.73 - glUseProgram(sdrprog); 3.74 + if(sdrprog) { 3.75 + int loc; 3.76 + if((loc = glGetUniformLocation(sdrprog, "lens_center_offset")) != -1) { 3.77 + float offset = vr_ctx.info.lens_center_offset * offs_scale[eye]; 3.78 + glUniform1f(loc, offset); 3.79 + } 3.80 3.81 - if(sdrprog) { 3.82 - int loc; 3.83 - if((loc = glGetUniformLocation(sdrprog, "lens_center_offset")) != -1) { 3.84 - float offset = vr_ctx.info.lens_center_offset * offs_scale[eye]; 3.85 - glUniform1f(loc, offset); 3.86 + if((loc = glGetUniformLocation(sdrprog, "tex_scale")) != -1) { 3.87 + glUniform2f(loc, tex_scale_x, tex_scale_y); 3.88 + } 3.89 } 3.90 3.91 - if((loc = glGetUniformLocation(sdrprog, "tex_scale")) != -1) { 3.92 - glUniform2f(loc, tex_scale_x, tex_scale_y); 3.93 + glBindTexture(GL_TEXTURE_2D, tex); 3.94 + glBegin(GL_QUADS); 3.95 + glColor4f(1, 1, 1, 1); 3.96 + glTexCoord2f(0, 0); glVertex2f(rects[eye][0], rects[eye][1]); 3.97 + glTexCoord2f(1, 0); glVertex2f(rects[eye][2], rects[eye][1]); 3.98 + glTexCoord2f(1, 1); glVertex2f(rects[eye][2], rects[eye][3]); 3.99 + glTexCoord2f(0, 1); glVertex2f(rects[eye][0], rects[eye][3]); 3.100 + glEnd(); 3.101 + 3.102 + glUseProgram(0); 3.103 + 3.104 + } else { 3.105 + 3.106 + if(!mesh_valid || tex_scale_x != prev_tex_scale_x || tex_scale_y != prev_tex_scale_y) { 3.107 + for(int i=0; i<2; i++) { 3.108 + int eye = i + VR_EYE_LEFT; 3.109 + 3.110 + if(wrapmesh[i].vbo) { 3.111 + glDeleteBuffers(1, &wrapmesh[i].vbo); 3.112 + } 3.113 + if(wrapmesh[i].ibo) { 3.114 + glDeleteBuffers(1, &wrapmesh[i].ibo); 3.115 + } 3.116 + 3.117 + float aspect = vr_ctx.info.aspect / 2.0; 3.118 + float offset = vr_ctx.info.lens_center_offset * offs_scale[eye]; 3.119 + wrapmesh[i] = gen_view_mesh(USUB, VSUB, aspect, offset, vr_ctx.info.scale, vr_ctx.info.distort, 3.120 + tex_scale_x, tex_scale_y); 3.121 + } 3.122 + mesh_valid = true; 3.123 + prev_tex_scale_x = tex_scale_x; 3.124 + prev_tex_scale_y = tex_scale_y; 3.125 } 3.126 + 3.127 + glScalef(quad_scale[eye], 1.0, 1.0); 3.128 + glTranslatef(quad_trans[eye], 0, 0); 3.129 + 3.130 + glUseProgram(0); 3.131 + glBindTexture(GL_TEXTURE_2D, tex); 3.132 + glEnable(GL_TEXTURE_2D); 3.133 + 3.134 + glColor3f(1, 1, 1); 3.135 + 3.136 + glEnableClientState(GL_VERTEX_ARRAY); 3.137 + glEnableClientState(GL_TEXTURE_COORD_ARRAY); 3.138 + 3.139 + int meshidx = eye - VR_EYE_LEFT; 3.140 + glBindBuffer(GL_ARRAY_BUFFER, wrapmesh[meshidx].vbo); 3.141 + glVertexPointer(3, GL_FLOAT, sizeof(Vertex), 0); 3.142 + glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), (void*)offsetof(Vertex, tx)); 3.143 + 3.144 + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, wrapmesh[meshidx].ibo); 3.145 + glDrawElements(GL_TRIANGLES, wrapmesh[meshidx].num_faces * 3, GL_UNSIGNED_INT, 0); 3.146 + 3.147 + glBindBuffer(GL_ARRAY_BUFFER, 0); 3.148 + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 3.149 + 3.150 + glDisableClientState(GL_VERTEX_ARRAY); 3.151 + glDisableClientState(GL_TEXTURE_COORD_ARRAY); 3.152 } 3.153 3.154 - glBindTexture(GL_TEXTURE_2D, tex); 3.155 - glBegin(GL_QUADS); 3.156 - glColor4f(1, 1, 1, 1); 3.157 - glTexCoord2f(0, 0); glVertex2f(rects[eye][0], rects[eye][1]); 3.158 - glTexCoord2f(1, 0); glVertex2f(rects[eye][2], rects[eye][1]); 3.159 - glTexCoord2f(1, 1); glVertex2f(rects[eye][2], rects[eye][3]); 3.160 - glTexCoord2f(0, 1); glVertex2f(rects[eye][0], rects[eye][3]); 3.161 - glEnd(); 3.162 - 3.163 - glUseProgram(0); 3.164 - 3.165 + glMatrixMode(GL_PROJECTION); 3.166 glPopMatrix(); 3.167 glMatrixMode(GL_MODELVIEW); 3.168 glPopMatrix(); 3.169 3.170 glPopAttrib(); 3.171 } 3.172 + 3.173 +static Mesh gen_view_mesh(int usub, int vsub, float aspect, float lens_center_offset, 3.174 + float scale, const float *dist_factors, float tex_scale_x, float tex_scale_y) 3.175 +{ 3.176 + int uverts = usub + 1; 3.177 + int vverts = vsub + 1; 3.178 + 3.179 + int num_verts = uverts * vverts; 3.180 + int num_quads = usub * vsub; 3.181 + int num_tris = num_quads * 2; 3.182 + 3.183 + Vertex *varr = new Vertex[num_verts]; 3.184 + unsigned int *iarr = new unsigned int[num_tris * 3]; 3.185 + 3.186 + float du = 1.0 / (float)usub; 3.187 + float dv = 1.0 / (float)vsub; 3.188 + 3.189 + Vertex *vptr = varr; 3.190 + for(int i=0; i<vverts; i++) { 3.191 + float v = (float)i * dv; 3.192 + float y = 2.0 * v - 1.0; 3.193 + 3.194 + for(int j=0; j<uverts; j++) { 3.195 + float u = (float)j * du; 3.196 + float x = 2.0 * u - 1.0; 3.197 + float tc[2] = {u, v}; 3.198 + 3.199 + distort_texcoords(tc, aspect, lens_center_offset, scale, dist_factors); 3.200 + 3.201 + vptr->x = x; 3.202 + vptr->y = y; 3.203 + vptr->z = 0; 3.204 + vptr->tx = tc[0] * tex_scale_x; 3.205 + vptr->ty = tc[1] * tex_scale_y; 3.206 + vptr++; 3.207 + } 3.208 + } 3.209 + 3.210 + unsigned int *iptr = iarr; 3.211 + for(int i=0; i<vsub; i++) { 3.212 + for(int j=0; j<usub; j++) { 3.213 + *iptr++ = i * uverts + j; 3.214 + *iptr++ = (i + 1) * uverts + j; 3.215 + *iptr++ = (i + 1) * uverts + (j + 1); 3.216 + 3.217 + *iptr++ = i * uverts + j; 3.218 + *iptr++ = (i + 1) * uverts + (j + 1); 3.219 + *iptr++ = i * uverts + (j + 1); 3.220 + } 3.221 + } 3.222 + 3.223 + unsigned int buf[2]; 3.224 + glGenBuffers(2, buf); 3.225 + glBindBuffer(GL_ARRAY_BUFFER, buf[0]); 3.226 + glBufferData(GL_ARRAY_BUFFER, num_verts * sizeof *varr, varr, GL_STATIC_DRAW); 3.227 + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf[1]); 3.228 + glBufferData(GL_ELEMENT_ARRAY_BUFFER, num_tris * 3 * sizeof *iarr, iarr, GL_STATIC_DRAW); 3.229 + 3.230 + delete [] varr; 3.231 + delete [] iarr; 3.232 + 3.233 + Mesh mesh; 3.234 + mesh.prim = GL_TRIANGLES; 3.235 + mesh.num_verts = num_verts; 3.236 + mesh.num_faces = num_tris; 3.237 + mesh.vbo = buf[0]; 3.238 + mesh.ibo = buf[1]; 3.239 + return mesh; 3.240 +} 3.241 + 3.242 +static void distort_texcoords(float *tc, float aspect, float lens_center_offset, float scale, const float *dist_factors) 3.243 +{ 3.244 + // map tc [0, 1] -> [-1, 1] 3.245 + float ptx = tc[0] * 2.0 - 1.0; 3.246 + float pty = tc[1] * 2.0 - 1.0; 3.247 + 3.248 + ptx += lens_center_offset * 2.0; 3.249 + pty /= aspect; // correct for aspect ratio 3.250 + 3.251 + float rad = barrel_scale(ptx * ptx + pty * pty, dist_factors); 3.252 + ptx *= rad; // scale the point by the computer distortion radius 3.253 + pty *= rad; 3.254 + 3.255 + ptx /= scale; 3.256 + pty /= scale; 3.257 + 3.258 + pty *= aspect; 3.259 + ptx -= lens_center_offset * 2.0; 3.260 + 3.261 + // map back to range [0, 1] 3.262 + tc[0] = ptx * 0.5 + 0.5; 3.263 + tc[1] = pty * 0.5 + 0.5; 3.264 +} 3.265 + 3.266 +static float barrel_scale(float rad, const float *k) 3.267 +{ 3.268 + float radsq = rad * rad; 3.269 + float radquad = radsq * radsq; 3.270 + return k[0] + k[1] * radsq + k[2] * radquad + k[3] * radquad * radsq; 3.271 +}