+#include <algorithm>
+#include <msp/gl/meshbuilder.h>
#include "stereocombiner.h"
+using namespace std;
+
+namespace {
+
+const char mirror_vs_source[] =
+ "uniform vec2 scale;\n"
+ "varying vec2 texcoord;\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = vec4(gl_Vertex.xy, 0.0, 1.0);\n"
+ " texcoord = gl_Vertex.xy*scale*0.5+0.5;\n"
+ "}";
+
+const char mirror_fs_source[] =
+ "uniform sampler2D texture;\n"
+ "varying vec2 texcoord;\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = texture2D(texture, texcoord);\n"
+ "}";
+
+}
+
+
namespace Msp {
-namespace GL {
+namespace VR {
StereoCombiner::StereoCombiner():
- width_div(1),
- height_div(1),
- keep_aspect(false)
+ target_width(0),
+ target_height(0),
+ render_aspect(1.0f),
+ frustum_skew(0.0f),
+ mirror(0)
+{ }
+
+void StereoCombiner::configure_eye_frustums(const Frustum &left_frustum, const Frustum &right_frustum)
+{
+ float vertical = max(max(left_frustum.top, -left_frustum.bottom), max(right_frustum.top, -right_frustum.bottom));
+ fov = Geometry::atan<float>(vertical)*2.0f;
+
+ float inner = max(left_frustum.right, -right_frustum.left);
+ float outer = max(-left_frustum.left, right_frustum.right);
+ frustum_skew = (inner-outer)/(inner+outer);
+
+ render_aspect = (inner+outer)/(vertical*2);
+}
+
+void StereoCombiner::set_mirroring(bool m)
+{
+ if(m && !mirror)
+ mirror = new MirrorView;
+ else if(!m && mirror)
+ {
+ delete mirror;
+ mirror = 0;
+ }
+}
+
+void StereoCombiner::render_mirror(const GL::Texture2D &tex) const
+{
+ if(!mirror)
+ return;
+
+ GL::Bind bind_tex(tex);
+ GL::Bind bind_shprog(mirror->shader);
+ mirror->shdata.apply();
+ mirror->mesh.draw();
+}
+
+
+StereoCombiner::Frustum::Frustum():
+ left(-1),
+ right(1),
+ bottom(-1),
+ top(1)
{ }
-} // namespace GL
+StereoCombiner::Frustum::Frustum(float l, float r, float b, float t):
+ left(l),
+ right(r),
+ bottom(b),
+ top(t)
+{ }
+
+
+StereoCombiner::MirrorView::MirrorView():
+ mesh(GL::VERTEX2),
+ shader(mirror_vs_source, mirror_fs_source)
+{
+ GL::MeshBuilder bld(mesh);
+ bld.begin(GL::TRIANGLE_STRIP);
+ bld.vertex(-1, 1);
+ bld.vertex(-1, -1);
+ bld.vertex(1, 1);
+ bld.vertex(1, -1);
+ bld.end();
+
+ shdata.uniform("scale", 0.5f, 0.5f);
+}
+
+} // namespace VR
} // namespace Msp