X-Git-Url: http://git.tdb.fi/?p=libs%2Fvr.git;a=blobdiff_plain;f=source%2Foculusriftcombiner.cpp;h=0cfd4ae1c6398701350c0a3c00114a0435447b8e;hp=e6b2908655a9a5d08520124b29e0a7dcbfe3ab21;hb=ed0489e44b7cb9748e5086e1e78ef65e1c3d1930;hpb=654b8083e06fb9f3338f7148bfd30b6305c7c5be diff --git a/source/oculusriftcombiner.cpp b/source/oculusriftcombiner.cpp index e6b2908..0cfd4ae 100644 --- a/source/oculusriftcombiner.cpp +++ b/source/oculusriftcombiner.cpp @@ -11,15 +11,27 @@ using namespace std; namespace { const char vs_source[] = + "uniform mat4 timewarp[2];\n" + "uniform vec2 uv_scale;\n" + "uniform vec2 uv_offset;\n" "varying vec2 texcoord_r;\n" "varying vec2 texcoord_g;\n" "varying vec2 texcoord_b;\n" + "varying float vignette;\n" + "vec2 apply_timewarp(vec2 coords, float factor)\n" + "{\n" + " vec4 coords4 = vec4(coords, 1.0, 1.0);\n" + " vec4 warped = mix(timewarp[0]*coords4, timewarp[1]*coords4, factor);\n" + " return (warped.xy/warped.z)*uv_scale+uv_offset;\n" + "}\n" "void main()\n" "{\n" " gl_Position = vec4(gl_Vertex.xy, 0.5, 1.0);\n" - " texcoord_r = gl_MultiTexCoord0.xy;\n" - " texcoord_g = gl_MultiTexCoord1.xy;\n" - " texcoord_b = gl_MultiTexCoord2.xy;\n" + " float tw_factor = gl_MultiTexCoord3.y;\n" + " texcoord_r = apply_timewarp(gl_MultiTexCoord0.xy, tw_factor);\n" + " texcoord_g = apply_timewarp(gl_MultiTexCoord1.xy, tw_factor);\n" + " texcoord_b = apply_timewarp(gl_MultiTexCoord2.xy, tw_factor);\n" + " vignette = gl_MultiTexCoord3.x;\n" "}\n"; const char fs_source[] = @@ -27,36 +39,28 @@ const char fs_source[] = "varying vec2 texcoord_r;\n" "varying vec2 texcoord_g;\n" "varying vec2 texcoord_b;\n" + "varying float vignette;\n" "void main()\n" "{\n" " float r = texture2D(texture, texcoord_r).r;\n" " float g = texture2D(texture, texcoord_g).g;\n" " float b = texture2D(texture, texcoord_b).b;\n" - " gl_FragColor = vec4(r, g, b, 1.0);\n" + " gl_FragColor = vec4(vec3(r, g, b)*vignette, 1.0);\n" "}\n"; void create_distortion_mesh(Msp::GL::Mesh &mesh, ovrHmd hmd, ovrEyeType eye, const ovrFovPort &fov) { ovrDistortionMesh ovr_mesh; - ovrHmd_CreateDistortionMesh(hmd, eye, fov, ovrDistortionCap_Chromatic, &ovr_mesh); - - ovrSizei tex_size = ovrHmd_GetFovTextureSize(hmd, eye, fov, 1.0); - ovrRecti view_rect; - view_rect.Pos.x = 0; - view_rect.Pos.y = 0; - view_rect.Size = tex_size; - ovrVector2f uv_scale_offset[2]; - ovrHmd_GetRenderScaleAndOffset(fov, tex_size, view_rect, uv_scale_offset); - ovrVector2f &scale = uv_scale_offset[0]; - ovrVector2f &offset = uv_scale_offset[1]; + ovrHmd_CreateDistortionMesh(hmd, eye, fov, ovrDistortionCap_Chromatic|ovrDistortionCap_Vignette|ovrDistortionCap_TimeWarp, &ovr_mesh); Msp::GL::MeshBuilder bld(mesh); for(unsigned i=0; iDefaultEyeFov[ovrEye_Left]; ovrFovPort right_fov = hmd->DefaultEyeFov[ovrEye_Right]; @@ -90,7 +91,7 @@ OculusRiftCombiner::OculusRiftCombiner(const OculusRiftDevice &d): float inner = max(left_fov.RightTan, right_fov.LeftTan); float outer = max(left_fov.LeftTan, right_fov.RightTan); - frustum_skew = (inner-outer)*2/(inner+outer); + frustum_skew = (inner-outer)/(inner+outer); left_fov.UpTan = right_fov.UpTan = vertical; left_fov.DownTan = right_fov.DownTan = vertical; @@ -101,21 +102,58 @@ OculusRiftCombiner::OculusRiftCombiner(const OculusRiftDevice &d): create_distortion_mesh(right_mesh, hmd, ovrEye_Right, right_fov); ovrSizei tex_size = ovrHmd_GetFovTextureSize(hmd, ovrEye_Left, left_fov, 1.0); - oversize = max(tex_size.w*2.0f/hmd->Resolution.w, tex_size.h*1.0f/hmd->Resolution.h); + width_factor = tex_size.w*1.0f/hmd->Resolution.w; + height_factor = tex_size.h*1.0f/hmd->Resolution.h; + float aspect = (inner+outer)/(vertical*2); + aspect_factor = aspect*hmd->Resolution.h/hmd->Resolution.w; - shdata.uniform("texture", 0); + left_shdata.uniform("texture", 0); + right_shdata.uniform("texture", 0); + ovrRecti view_rect; + view_rect.Pos.x = 0; + view_rect.Pos.y = 0; + view_rect.Size = tex_size; + ovrVector2f uv_scale_offset[2]; + ovrHmd_GetRenderScaleAndOffset(left_fov, tex_size, view_rect, uv_scale_offset); + left_shdata.uniform("uv_scale", uv_scale_offset[0].x, -uv_scale_offset[0].y); + left_shdata.uniform("uv_offset", uv_scale_offset[1].x, 1-uv_scale_offset[1].y); + ovrHmd_GetRenderScaleAndOffset(right_fov, tex_size, view_rect, uv_scale_offset); + right_shdata.uniform("uv_scale", uv_scale_offset[0].x, -uv_scale_offset[0].y); + right_shdata.uniform("uv_offset", uv_scale_offset[1].x, 1-uv_scale_offset[1].y); } void OculusRiftCombiner::render(const GL::Texture2D &left, const GL::Texture2D &right) const { GL::Bind bind_shprog(shprog); - shdata.apply(); + + ovrHmd hmd = device.get_private().ovr_hmd; + + if(device.is_timing_active()) + { + ovr_WaitTillTime(device.get_timewarp_time()); + ovrTrackingState state = ovrHmd_GetTrackingState(hmd, device.get_tracking_time()); + + ovrMatrix4f matrices[2]; + ovrHmd_GetEyeTimewarpMatrices(hmd, ovrEye_Left, state.HeadPose.ThePose, matrices); + left_shdata.uniform_matrix4_array("timewarp", 2, &matrices[0].M[0][0]); + + ovrHmd_GetEyeTimewarpMatrices(hmd, ovrEye_Right, state.HeadPose.ThePose, matrices); + right_shdata.uniform_matrix4_array("timewarp", 2, &matrices[0].M[0][0]); + } + else + { + GL::Matrix matrices[2]; + left_shdata.uniform_matrix4_array("timewarp", 2, matrices[0].data()); + right_shdata.uniform_matrix4_array("timewarp", 2, matrices[0].data()); + } GL::Bind bind_tex(left); + left_shdata.apply(); left_mesh.draw(); right.bind(); + right_shdata.apply(); right_mesh.draw(); }