2 #include <msp/gl/meshbuilder.h>
3 #include <msp/gl/texture2d.h>
4 #include "oculusriftcombiner.h"
5 #include "oculusriftdevice.h"
6 #include "oculusriftdevice_private.h"
13 const char vs_source[] =
14 "varying vec2 texcoord_r;\n"
15 "varying vec2 texcoord_g;\n"
16 "varying vec2 texcoord_b;\n"
17 "varying float vignette;\n"
20 " gl_Position = vec4(gl_Vertex.xy, 0.5, 1.0);\n"
21 " texcoord_r = gl_MultiTexCoord0.xy;\n"
22 " texcoord_g = gl_MultiTexCoord1.xy;\n"
23 " texcoord_b = gl_MultiTexCoord2.xy;\n"
24 " vignette = gl_MultiTexCoord3.x;\n"
27 const char fs_source[] =
28 "uniform sampler2D texture;\n"
29 "varying vec2 texcoord_r;\n"
30 "varying vec2 texcoord_g;\n"
31 "varying vec2 texcoord_b;\n"
32 "varying float vignette;\n"
35 " float r = texture2D(texture, texcoord_r).r;\n"
36 " float g = texture2D(texture, texcoord_g).g;\n"
37 " float b = texture2D(texture, texcoord_b).b;\n"
38 " gl_FragColor = vec4(vec3(r, g, b)*vignette, 1.0);\n"
41 void create_distortion_mesh(Msp::GL::Mesh &mesh, ovrHmd hmd, ovrEyeType eye, const ovrFovPort &fov)
43 ovrDistortionMesh ovr_mesh;
44 ovrHmd_CreateDistortionMesh(hmd, eye, fov, ovrDistortionCap_Chromatic|ovrDistortionCap_Vignette, &ovr_mesh);
46 ovrSizei tex_size = ovrHmd_GetFovTextureSize(hmd, eye, fov, 1.0);
50 view_rect.Size = tex_size;
51 ovrVector2f uv_scale_offset[2];
52 ovrHmd_GetRenderScaleAndOffset(fov, tex_size, view_rect, uv_scale_offset);
53 ovrVector2f &scale = uv_scale_offset[0];
54 ovrVector2f &offset = uv_scale_offset[1];
56 Msp::GL::MeshBuilder bld(mesh);
57 for(unsigned i=0; i<ovr_mesh.VertexCount; ++i)
59 ovrDistortionVertex &v = ovr_mesh.pVertexData[i];
60 bld.multitexcoord(0, v.TanEyeAnglesR.x*scale.x+offset.x, 1.0f-(v.TanEyeAnglesR.y*scale.y+offset.y));
61 bld.multitexcoord(1, v.TanEyeAnglesG.x*scale.x+offset.x, 1.0f-(v.TanEyeAnglesG.y*scale.y+offset.y));
62 bld.multitexcoord(2, v.TanEyeAnglesB.x*scale.x+offset.x, 1.0f-(v.TanEyeAnglesB.y*scale.y+offset.y));
63 bld.multitexcoord(3, v.VignetteFactor);
64 bld.vertex(v.ScreenPosNDC.x, v.ScreenPosNDC.y);
67 Msp::GL::Batch batch(Msp::GL::TRIANGLES);
68 batch.append(vector<unsigned>(ovr_mesh.pIndexData, ovr_mesh.pIndexData+ovr_mesh.IndexCount));
69 mesh.add_batch(batch);
71 ovrHmd_DestroyDistortionMesh(&ovr_mesh);
79 OculusRiftCombiner::OculusRiftCombiner(const OculusRiftDevice &d):
81 left_mesh((GL::VERTEX2, GL::TEXCOORD2,0, GL::TEXCOORD2,1, GL::TEXCOORD2,2, GL::TEXCOORD1,3)),
82 right_mesh((GL::VERTEX2, GL::TEXCOORD2,0, GL::TEXCOORD2,1, GL::TEXCOORD2,2, GL::TEXCOORD1,3)),
83 shprog(vs_source, fs_source)
85 const OculusRiftDevice::Private &dev_priv = device.get_private();
86 ovrHmd hmd = dev_priv.ovr_hmd;
88 ovrFovPort left_fov = hmd->DefaultEyeFov[ovrEye_Left];
89 ovrFovPort right_fov = hmd->DefaultEyeFov[ovrEye_Right];
90 float vertical = max(max(left_fov.UpTan, left_fov.DownTan), max(right_fov.UpTan, right_fov.DownTan));
91 fov = Geometry::atan<float>(vertical)*2.0f;
93 float inner = max(left_fov.RightTan, right_fov.LeftTan);
94 float outer = max(left_fov.LeftTan, right_fov.RightTan);
95 frustum_skew = (inner-outer)/(inner+outer);
97 left_fov.UpTan = right_fov.UpTan = vertical;
98 left_fov.DownTan = right_fov.DownTan = vertical;
99 left_fov.RightTan = right_fov.LeftTan = inner;
100 left_fov.LeftTan = right_fov.RightTan = outer;
102 create_distortion_mesh(left_mesh, hmd, ovrEye_Left, left_fov);
103 create_distortion_mesh(right_mesh, hmd, ovrEye_Right, right_fov);
105 ovrSizei tex_size = ovrHmd_GetFovTextureSize(hmd, ovrEye_Left, left_fov, 1.0);
106 width_factor = tex_size.w*1.0f/hmd->Resolution.w;
107 height_factor = tex_size.h*1.0f/hmd->Resolution.h;
108 float aspect = (inner+outer)/(vertical*2);
109 aspect_factor = aspect*hmd->Resolution.h/hmd->Resolution.w;
111 shdata.uniform("texture", 0);
115 void OculusRiftCombiner::render(const GL::Texture2D &left, const GL::Texture2D &right) const
117 GL::Bind bind_shprog(shprog);
120 GL::Bind bind_tex(left);